By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,194 Members | 847 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,194 IT Pros & Developers. It's quick & easy.

Numerical Algorithm: floor to round to the nearest hundredth

P: n/a
I have a program in which I need to take a numeric value for dollars.
There is a "set" function that must screen the value for the following
3 conditions with the indicated handling functionality:

1. Non-negative ==set to $0.00
2. Out of range (more than 10 digits to represent) ==set to $0.00
3. More than 2 decimal places ==truncate to 2.

I have the first two cases down.

I am having trouble with the floor function. If the input is 8.2, the
cost should be interpreted as $8.20, but this is not the case.

Using the algorithm I have right now, the entry condition to process
the number is the following where c is a double representing the cost.

if ( (c*100) != floor(c*100) ) {
c = floor(c*100)/100;
}

Why won't this work? First of all, it enters this block of code for
8.2, which it should not. 820 should equal the floored version of
820, right? wrong. The floored version comes out as 819.

For anything with 3 or more decimal places represented, it functions
as expected. For any number of the form x.y where y is between 0 and
5, exclusive, the block above will run, and the value will be
unchanged. Why??? I also have a cout statement in this block
indicating that the number had too many decimal places, and that it
had been truncated to ___. It says that it was truncated to the
original value, of course.

Am I missing something here? Why do those numbers enter this block?
10.325 is processed to 10.32 as expected, and 8.5 generates no errors
at all, but 3.8 enters the loop and comes out unchanged, as does 8.2.

Anyone?

I have also tried casting down to int and back to double for the
comparison, to truncate the fractional part of the number with the
cast; this does not help.

Mar 23 '07 #1
Share this Question
Share on Google+
4 Replies


P: n/a
On 3月23日, 上午10時05分, "lilma...@gmail.com" <lilma....@gmail.comwrote:
I have a program in which I need to take a numeric value for dollars.
There is a "set" function that must screen the value for the following
3 conditions with the indicated handling functionality:

1. Non-negative ==set to $0.00
2. Out of range (more than 10 digits to represent) ==set to $0.00
3. More than 2 decimal places ==truncate to 2.

I have the first two cases down.

I am having trouble with the floor function. If the input is 8.2, the
cost should be interpreted as $8.20, but this is not the case.

Using the algorithm I have right now, the entry condition to process
the number is the following where c is a double representing the cost.

if ( (c*100) != floor(c*100) ) {
c = floor(c*100)/100;

}

Why won't this work? First of all, it enters this block of code for
8.2, which it should not. 820 should equal the floored version of
820, right? wrong. The floored version comes out as 819.

For anything with 3 or more decimal places represented, it functions
as expected. For any number of the form x.y where y is between 0 and
5, exclusive, the block above will run, and the value will be
unchanged. Why??? I also have a cout statement in this block
indicating that the number had too many decimal places, and that it
had been truncated to ___. It says that it was truncated to the
original value, of course.

Am I missing something here? Why do those numbers enter this block?
10.325 is processed to 10.32 as expected, and 8.5 generates no errors
at all, but 3.8 enters the loop and comes out unchanged, as does 8.2.

Anyone?

I have also tried casting down to int and back to double for the
comparison, to truncate the fractional part of the number with the
cast; this does not help.
You forget considering the effect of the round-off error of the
floating-point numbers.

Mar 23 '07 #2

P: n/a
li******@gmail.com wrote:
I have a program in which I need to take a numeric value for dollars.
There is a "set" function that must screen the value for the following
3 conditions with the indicated handling functionality:

1. Non-negative ==set to $0.00
2. Out of range (more than 10 digits to represent) ==set to $0.00
3. More than 2 decimal places ==truncate to 2.

I have the first two cases down.

I am having trouble with the floor function. If the input is 8.2, the
cost should be interpreted as $8.20, but this is not the case.
Why not just multiply the values by 100 and assign to an int? Then you
can work in cents.

--
Ian Collins.
Mar 23 '07 #3

P: n/a
On 3月23日, 上午10時05分, "lilma...@gmail.com" <lilma....@gmail.comwrote:
I have a program in which I need to take a numeric value for dollars.
There is a "set" function that must screen the value for the following
3 conditions with the indicated handling functionality:

1. Non-negative ==set to $0.00
2. Out of range (more than 10 digits to represent) ==set to $0.00
3. More than 2 decimal places ==truncate to 2.

I have the first two cases down.

I am having trouble with the floor function. If the input is 8.2, the
cost should be interpreted as $8.20, but this is not the case.

Using the algorithm I have right now, the entry condition to process
the number is the following where c is a double representing the cost.

if ( (c*100) != floor(c*100) ) {
c = floor(c*100)/100;

}

Why won't this work? First of all, it enters this block of code for
8.2, which it should not. 820 should equal the floored version of
820, right? wrong. The floored version comes out as 819.

For anything with 3 or more decimal places represented, it functions
as expected. For any number of the form x.y where y is between 0 and
5, exclusive, the block above will run, and the value will be
unchanged. Why??? I also have a cout statement in this block
indicating that the number had too many decimal places, and that it
had been truncated to ___. It says that it was truncated to the
original value, of course.

Am I missing something here? Why do those numbers enter this block?
10.325 is processed to 10.32 as expected, and 8.5 generates no errors
at all, but 3.8 enters the loop and comes out unchanged, as does 8.2.

Anyone?

I have also tried casting down to int and back to double for the
comparison, to truncate the fractional part of the number with the
cast; this does not help.
To resolve the round-off problem, you may add a tiny amount, e.g.
1.e-10, to your number.
e.g.

Try this :

int main() {

const double TOL = 1.e-10 ;
double a ;

cout << setprecision(2) << fixed ;
for ( a = 0 ; a < 20 ; a += 0.1 ) {
cout << a << "\t"
<< floor((a+TOL)*100)/100. << endl ;
}

return 0 ;
}
If you set the TOL to zero, then you'll see the round-off problem
again.
BTW, The amount of TOL is problem-dependent.

Mar 23 '07 #4

P: n/a
On Mar 22, 10:13 pm, "weihan" <wei...@math.ncu.edu.twwrote:
On 323, 銝1005, "lilma...@gmail.com" <lilma...@gmail.comwrote:
I have a program in which I need to take a numeric value for dollars.
There is a "set" function that must screen the value for the following
3 conditions with the indicated handling functionality:
1. Non-negative ==set to $0.00
2. Out of range (more than 10 digits to represent) ==set to $0.00
3. More than 2 decimal places ==truncate to 2.
I have the first two cases down.
I am having trouble with the floor function. If the input is 8.2, the
cost should be interpreted as $8.20, but this is not the case.
Using the algorithm I have right now, the entry condition to process
the number is the following where c is a double representing the cost.
if ( (c*100) != floor(c*100) ) {
c = floor(c*100)/100;
}
Why won't this work? First of all, it enters this block of code for
8.2, which it should not. 820 should equal the floored version of
820, right? wrong. The floored version comes out as 819.
For anything with 3 or more decimal places represented, it functions
as expected. For any number of the form x.y where y is between 0 and
5, exclusive, the block above will run, and the value will be
unchanged. Why??? I also have a cout statement in this block
indicating that the number had too many decimal places, and that it
had been truncated to ___. It says that it was truncated to the
original value, of course.
Am I missing something here? Why do those numbers enter this block?
10.325 is processed to 10.32 as expected, and 8.5 generates no errors
at all, but 3.8 enters the loop and comes out unchanged, as does 8.2.
Anyone?
I have also tried casting down to int and back to double for the
comparison, to truncate the fractional part of the number with the
cast; this does not help.

To resolve the round-off problem, you may add a tiny amount, e.g.
1.e-10, to your number.
e.g.

Try this :

int main() {

const double TOL = 1.e-10 ;
double a ;

cout << setprecision(2) << fixed ;
for ( a = 0 ; a < 20 ; a += 0.1 ) {
cout << a << "\t"
<< floor((a+TOL)*100)/100. << endl ;
}

return 0 ;

}

If you set the TOL to zero, then you'll see the round-off problem
again.
BTW, The amount of TOL is problem-dependent.
thanks to both of you - it turned out that the project compiled and
ran without error, logic or otherwise, a couple days later. I don't
know if it was a temporary thing with the compiler or what, but it
works now. Thanks for the tips - will remember for next time!

Apr 5 '07 #5

This discussion thread is closed

Replies have been disabled for this discussion.