Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I write a C++ function returning true if a real number is exactly representable with a double?

How can I write a C++ function returning true if a real number is exactly representable with a double?

bool isRepresentable( const char* realNumber )
{
   bool answer = false;
   // what goes here?
   return answer;
}

Simple tests:

assert( true==isRepresentable( "0.5" ) );
assert( false==isRepresentable( "0.1" ) );
like image 792
Alessandro Jacopson Avatar asked Nov 04 '08 15:11

Alessandro Jacopson


2 Answers

Parse the number into the form a + N / (10^k), where a and N are integers, and k is the number of decimal places you have.

Example: 12.0345 -> 12 + 345 / 10^4, a = 12, N = 345, k = 4

Now, 10^k = (2 * 5) ^ k = 2^k * 5^k

You can represent your number as exact binary fraction if and only if you get rid of the 5^k term in the denominator.

The result would check (N mod 5^k) == 0

like image 62
Alexei Avatar answered Nov 14 '22 20:11

Alexei


Holy homework, batman! :)

What makes this interesting is that you can't simply do an (atof|strtod|sscanf) -> sprintf loop and check whether you got the original string back. sprintf on many platforms detects the "as close as you can get to 0.1" double and prints it as 0.1, for example, even though 0.1 isn't precisely representable.

#include <stdio.h>

int main() {
    printf("%llx = %f\n",0.1,0.1);
}

prints: 3fb999999999999a = 0.100000

on my system.

The real answer probably would require parsing out the double to convert it to an exact fractional representation (0.1 = 1/10) and then making sure that the atof conversion times the denominator equals the numerator.

I think.

like image 5
Mike G. Avatar answered Nov 14 '22 20:11

Mike G.