?
Solved

Weird problem with DOUBLE datatype in VC++

Posted on 2014-03-29
14
Medium Priority
?
384 Views
Last Modified: 2014-04-01
Hi Experts,

I am encountering a weird problem using double datatype in my VC++ application.

For ex:

double x = 132.23

When I debug what "x" is actually having, it shows me "132.22999999999999"

I thought this is understood because as double stores the floating point numbers in base 2 and as 0.23 CANNOT be absolutely represented in base 2, there is some rounding issue when converting back to decimal and so I see an error of  .00000000000001 due to precision limits.

However, when I change it to

double x = 132.16

X shows to be having exactly "132.16"!!

I dont understand how this is possible because I thought .16 cannot be absolutely represented in base 2!

Why do I see this difference? Any help would be greatly appreciated
0
Comment
Question by:aravindgopaluni
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
  • 3
  • +1
14 Comments
 
LVL 84

Accepted Solution

by:
Dave Baldwin earned 1000 total points
ID: 39964023
Floating point (double) stores the whole number in a binary format, not just the part after the decimal.  The number also includes an exponent to set the value to the correct range.  On this page http://www.h-schmidt.net/FloatConverter/IEEE754.html is a floating point calculator that shows how it all works.
0
 
LVL 35

Assisted Solution

by:sarabande
sarabande earned 1000 total points
ID: 39964024
it is indeed the case that the "same" floating point number may have two or more representations internally. if you make an assignment you are safe. it always will choose the same representation (not the one with the 99999 at end). however any division or multiplication gives an result where mantissa and exponent were calculated separatly and therefore the conversion to decimals can be different. note, also in math, the numbers 1.00000.... is equal to 0.99999....

the entire double-precision number uses 1 bit for sign, 11 bits for exponent and 52 bits for fraction (mantissa). a number is described in IEEE 754 by:

(-1)^sign * 2^(exponent - exponent bias) * 1.mantissa

In the case of subnormals(E=0) the double-precision number is described by:

(-1)^sign *  2^(1 - exponent bias) * 0.mantissa

if you want to compare doubles or have to output them you always need to consider a little rounding difference.

a good description you find at wikipedia or http://www.cquestions.com/2009/06/memory-representation-of-double-in-c.html

Sara
0
 
LVL 35

Expert Comment

by:sarabande
ID: 39964026
sorry Dave, didn't want to repeat ...

Sara
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 84

Expert Comment

by:Dave Baldwin
ID: 39964030
No problem.
0
 

Author Comment

by:aravindgopaluni
ID: 39964091
Thank you for your answers.

I understand that double saves the whole number in base 2 (binary). However, what I couldn't understand is why in my VC++ application 132.23 is represented as 132.22999999999 while 132.16 is represented as 132.16 (absolute value) when both of these numbers result in infinite recurring when attempting to convert into base 2.

I used the calculator you provided and this is what it shows:

For 132.23

Decimal Representation      132.23
Binary Representation               01000011000001000011101011100001
Hexadecimal Representation      0x43043ae1
After casting to double precision      132.22999572753906

For 132.16

Decimal Representation      132.16
Binary Representation              01000011000001000010100011110110
Hexadecimal Representation      0x430428f6
After casting to double precision 132.16000366210938

So, when I do the below:

double x = 132.16

I thought x would have some indication of the overflowing base 2 conversion and so was surprised that it did not.

Issue here is I am saving this value to Oracle database and when somebody else is trying to pul the data, they complain about the discrepancy.

Is there a way I can make double to save unto only 2 decimal digits?

I tried doing floor(x*100.0 + 0.5)/100.0 but nothing seems to work.
0
 
LVL 84

Expert Comment

by:Dave Baldwin
ID: 39964117
For Oracle and most SQL databases, you need to use the DECIMAL datatype.  http://docs.oracle.com/javadb/10.6.2.1/ref/rrefsqlj15260.html  It doesn't have that problem.  But All IEEE754 floating point versions will have that problem.
0
 
LVL 15

Expert Comment

by:ChloesDad
ID: 39964125
I'm not sure about saving the numbers as two decimal places, this will depend on your database structure, but you can certainly display the number to 2dp using tostring.
0
 
LVL 35

Expert Comment

by:sarabande
ID: 39965169
what I couldn't understand is why in my VC++ application 132.23 is represented as 132.22999999999 while 132.16 is represented as 132.16 (absolute value)

132.22999999999 is not a representation but output (presentation). when converting from base 2 to base 10 small rounding differences at the end of the precision (means after 15 - 17 decimal digits) are normal and cannot prevented principally. only the output can be made rightly by active rounding.

std::cout << std::fixed << std::setprecision(2) << mydouble; // two digits after decimal point

Open in new window


Sara
0
 
LVL 84

Expert Comment

by:Dave Baldwin
ID: 39965180
@aravindgopaluni, while you can do the display formatting in your own program, if the other people are using different software to access the database, they will see this problem as long as you are storing the values as floating point values.  The only way they will see the values with 2 correct decimal values is if you use the DECIMAL datatype in the database.  Even then, you will have to correctly format your values from floating point to correct decimal representation in your program before you store them in the database.
0
 

Author Comment

by:aravindgopaluni
ID: 39967193
Thanks Dave & Sara. Appreciate your time.

Sorry about the naive terminology I used when I said "representation" but essentially, I meant the output of the double variable.

So, even though both 132.23 and 132.16 cannot be finitely stored in base 2, do you think the reason I see the output as "132.16" in the latter case and not in the former is because of the rounding errors that cannot be avoided when converting back to base 10?

Thanks,
0
 
LVL 84

Expert Comment

by:Dave Baldwin
ID: 39967263
That's pretty much it.
0
 

Author Closing Comment

by:aravindgopaluni
ID: 39967463
Both answers are helpful but the app forces me to select only one of them for "best". Sorry about that!
0
 
LVL 84

Expert Comment

by:Dave Baldwin
ID: 39967638
No problem, glad to help.
0
 
LVL 35

Expert Comment

by:sarabande
ID: 39968905
thank you. it is all fine.

Sara
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question