Re: .11 * 100 trouble in C++
1) 0.11 can not be stored exactly ... there are numerous threads
on this.
2) your calculations are not the same. In the first calculation 0.11
is a double , in the second it it a float
Re: .11 * 100 trouble in C++
It is impossible to get "a correct result" in such a case. It would be the same as to exactly express the 1/3 with a decimal fraction (0.3333333333....)
Re: .11 * 100 trouble in C++
also try "* 100.0" rather than "* 100".
Re: .11 * 100 trouble in C++
Quote:
Originally Posted by jim enright
also try "* 100.0" rather than "* 100".
Why? What is the difference? :confused:
Re: .11 * 100 trouble in C++
Quote:
Originally Posted by zspirit
...
Code:
short int test = .11 * 100; // test is right 11.
// case 2
float fVal = .11;
short int test = fVal * 100; // now test is .10
To increase the precision of such calculations you should use double rather than float and long rather than short.
Re: .11 * 100 trouble in C++
I don't think .11 is any of those numbers which can not be represented, the first case stands example (.11 * 100 = .11 is hold correctly in that variable).
if you check float fVal = .11, it also holds it correctly, things change when it is multiplied by 100 and yes float of course can hold 11.00 and so does short int.
I am storing the value as short int, and I simply need to move that value from float to it. If you care curious shy short int, the value never exceeds 1,000 and the float is always 2 decimal places max.
I am surprized any typcasting even does not work!
Re: .11 * 100 trouble in C++
Don't haqve a floating point binary calculator with me, but I can assure you that 0.1 is a repeating infinite binary pattern. :eek:
Re: .11 * 100 trouble in C++
Quote:
Originally Posted by TheCPUWizard
Don't haqve a floating point binary calculator with me, but I can assure you that 0.1 is a repeating infinite binary pattern. :eek:
what I am trying now is use doubles but even that has some issues.
double dVal = (double) fVal;
where as fVal = .11, dVal is .1099999...
If I can transfer the fVal of .11 into dVal, that will make me happy..what should I do? typecasting does not work.
Re: .11 * 100 trouble in C++
Quote:
Originally Posted by zspirit
I don't think .11 is any of those numbers which can not be represented,
Care for a math lesson in binary?
The only numbers that can be represented exacty on a binary system such as a computer are numbers that are sums of negative powers of 2. For example,
0.5, 0.75, 0,125, 0.625, etc. can be represented exactly in binary, since (taking the first and second examples)
0.5 = 1/(2^1) = 1/2
0.75 = 1 / (2^1) + 1 / (2^2) = 1/2 + 1/4 = 3/4
You can figure out the rest. A number such as 0.11 cannot be represented as sums of powers of 2 in the denominator, no matter how hard you try. It is a repeating, non-terminating binary number.
0.11 = 0.00011100001010001111010111000010100011110101110000101001...
There is no end to the string of digits, and note the pattern repeats after the 23rd (I hope I counted right) digit.
So 0.11 cannot be represented exactly, as I've shown you here. If you want to see how to do the math to translate a decimal fraction to a binary fraction, you can go here:
http://cs.furman.edu/digitaldomain/m...rac_to_bin.htm
Regards,
Paul McKenzie
Re: .11 * 100 trouble in C++
Quote:
Originally Posted by zspirit
what I am trying now is use doubles but even that has some issues.
double dVal = (double) fVal;
where as fVal = .11, dVal is .1099999...
If I can transfer the fVal of .11 into dVal, that will make me happy..what should I do? typecasting does not work.
When you convert a float into a double, you've already lost the precision. Store it as a double to begin with, instead of a float. It's like taking a .jpg image and saving it as a .png or .gif, and hoping to get back the data you lost in the original compression. It's already gone.
But what you're trying to do is going to be a problem no matter what. When a float or double value is converted to an integer, it simply truncates any non-integer data. Since the float representation of an integer can always look something like 'x.999999999999999', it will *always* truncate that data when cast to an int.
There are ways to fix the problem, but you have to think about what you really want to do. If the result is 10.8, do you want that to be converted to 10, or 11? Do you want to round the number, or just truncate the decimal portion?
It's a potentially dangerous operation, no matter what you do. And that's why it generates a compiler warning. The first thing I'd tell any new programmer is to always make sure the option "treat warnings as errors" is enabled. Warnings are the compiler's way of letting you know that you're doing things which might be dangerous, if you haven't thought them through. And that's a good thing. It's better to let the compiler catch errors than to find them yourself.
Re: .11 * 100 trouble in C++
Quote:
Originally Posted by kyoryu
When you convert a float into a double, you've already lost the precision. Store it as a double to begin with, instead of a float. It's like taking a .jpg image and saving it as a .png or .gif, and hoping to get back the data you lost in the original compression. It's already gone.
so I was relying on the fact the fVal still correctly says the value is .11 (you can see in debugger), so I thought converting it to double should go smooth since float can hold .11, double can too.
Do you seem to suggest that even though fVal says it's value is .11, but in fact it's not?
I am confused because if float can not hold .11 than it has enough decimal points to dislay it something else like say .109999 for, why it doesn't do that? :confused:
Re: .11 * 100 trouble in C++
Quote:
Originally Posted by Paul McKenzie
Care for a math lesson in binary?
The only numbers that can be represented exacty on a binary system such as a computer are numbers that are sums of negative powers of 2. For example,
0.5, 0.75, 0,125, 0.625, etc. can be represented exactly in binary, since (taking the first and second examples)
0.5 = 1/(2^1) = 1/2
0.75 = 1 / (2^1) + 1 / (2^2) = 1/2 + 1/4 = 3/4
You can figure out the rest. A number such as 0.11 cannot be represented as sums of powers of 2 in the denominator, no matter how hard you try. It is a repeating, non-terminating binary number.
0.11 = 0.00011100001010001111010111000010100011110101110000101001...
There is no end to the string of digits, and note the pattern repeats after the 23rd (I hope I counted right) digit.
So 0.11 cannot be represented exactly, as I've shown you here. If you want to see how to do the math to translate a decimal fraction to a binary fraction, you can go here:
http://cs.furman.edu/digitaldomain/m...rac_to_bin.htm
Regards,
Paul McKenzie
Bear with me if I sound silly but in that case looks like .11 can not be truely represented even by double? Why should double help!
Re: .11 * 100 trouble in C++
Because you're confusing with the formatted output of the float value, with the actual float value. They're not the same.
A float doesn't hold '.11'. It holds a collection of bits which are *approximately* .11. The debugger, when it outputs the value, does some internal conversions to decide how to print out the number.
When you convert that .11 to a double, you're converting the bits which represent it into a double. And the double can only be an approximation of .11, anyway.
When you cast from a float or double to an int, those "best-guess" efforts don't happen. They add complexity, so C just does the straightforward thing and lets you figure out what you actually want to happen. No point in incurring the cost for something that's not always needed.
At any rate, casting from a float to an int is something you need to be careful with. You need to think about what you want the output to be for non-integer results. As an example, do you want 10.5 to be converted to 10, or 11?
And using a double can help because it allows the internal representation of the value to be *closer* to the actual value you want. You're adding precision. But, double or float, the casting issue still remains.
Another good idea when going between floats and ints is to only convert to an integer when you are absolutely sure you are done with all calculations.
See what this code does:
Code:
float fval = .11f;
float valAsFloatFromFloatByFloat = fval * 100.f;
int valAsIntFromFloatByFloat = fval * 100.f;
int valAsIntFromFloatByInt = fval * 100;
float valAsFloatFromFloatByInt = fval * 100;
printf("%d %d %d %d\n", (int)valAsFloatFromFloatByFloat,
valAsIntFromFloatByFloat,
(int)valAsFloatFromFloatByInt,
valAsIntFromFloatByInt);
Re: .11 * 100 trouble in C++
It seems that all you want to do is take a fractional decimal number and turn it into an int with the same digits? For example:
.11 to 11
.12 to 12
.17 to 17
.359 to 359
.7 to 7
and so on?
However, as pointed out, fractions not in the series of fractional powers of two (as values or sums of values) cannot be represented in binary. I would attempt two solutions:
First solution (rely on rounding):
(int)(.11 * 100 + .005) should always produce 11
(int)(.9 * 10 + .05) should always produce 9
(int)(.359 * 1000 + .0005) should always produce 359
The idea is to use a multiple of 10 that is equal to the number of decimal places, and add a value equal to 5 times a negative multiple of 10. The negative mulitiple would be one more than the multiple of the original number.
Second solution:
If the fractional numbers are inputs to your program, and if you have control of the input code, then you could have the inputs come in as strings. Use a library function ... ispunct() ... is one that I can think of, to remove the decimal point, and then convert the string to an int.
Re: .11 * 100 trouble in C++
Re: .11 * 100 trouble in C++
Quote:
Originally Posted by kyoryu
At any rate, casting from a float to an int is something you need to be careful with. You need to think about what you want the output to be for non-integer results. As an example, do you want 10.5 to be converted to 10, or 11?
Just to clarify, what I want to do is this: Give are set of float values essentially with 2 decimal places. The goal is eliminate the decimal point and get the integer value, which means simply multiply be 100.
12.34 -> 1234
Now I am going to eliminate float i think and store th original value in doubles.
Re: .11 * 100 trouble in C++
On second thought:
Quote:
First solution (rely on rounding):
(int)(.11 * 100 + .005) should always produce 11
(int)(.9 * 10 + .05) should always produce 9
(int)(.359 * 1000 + .0005) should always produce 359
It would be less complicated to do it this way:
(int)(.11 * 100 + .5)
(int)(.9 * 10 + .5)
(int)(.359 * 1000 + .5)
Re: .11 * 100 trouble in C++
Quote:
Originally Posted by zspirit
Just to clarify, what I want to do is this: Give are set of float values essentially with 2 decimal places. The goal is eliminate the decimal point and get the integer value, which means simply multiply be 100.
12.34 -> 1234
Now I am going to eliminate float i think and store th original value in doubles.
How are you reading the information in in the first place? Given that you always want to store the information as an int, it may be easier to never actually use a float.
How reasonable this is is dependent on how you're getting the data.
Though, whether you store as float or double, you'll be better off if you always use the same data type for all caclulations, and then convert to int at the end of it all.
See the code I posted for an example of this.
Re: .11 * 100 trouble in C++
Here is the solution!!!
From the original post:
Code:
// case 2
float fVal = .11;
short int test = (short int) (float) (fVal * 100); // now this right!
The trick is to typecast it first to float and than to short int!!! ahhh
if we don't typecast to float, the result is treated as double and with high precision its value becomes .1099999, multiply this by 100 is 10.9, typecast this to int gives 10
typecasting 10.9 to int would simply discard the .9 part but typecasting it to float first will still work with .9 part because it is float and its value is read as 11.
:D
Re: .11 * 100 trouble in C++
Quote:
Originally Posted by zspirit
Here is the solution!!!
From the original post:
Code:
// case 2
float fVal = .11;
short int test = (short int) (float) (fVal * 100); // now this right!
The trick is to typecast it first to float and than to short int!!! ahhh
if we don't typecast to float, the result is treated as double and with high precision its value becomes .1099999, multiply this by 100 is 10.9, typecast this to int gives 10
typecasting 10.9 to int would simply discard the .9 part but typecasting it to float first will still work with .9 part because it is float and its value is read as 11.
:D
It don't work
try declaring fVal like double directly
Sorry, my english is not good