Displaying a small double in in decimal, not scientific format C++ /CLR - c++-cli

I have doubles like 0.00006 which when displaying switch to the scientific format (something like 6E-05).
I tried Math::Round(doublenumber, 5) but it cant round numbers smaller than 0.0001. So rounding 0.00016 works fine, but 0.00006 doesnt, I want to print 0.00006 and not the scientific number in my form.
Any help?

Use Double.ToString(String^) with the "F" format string. This forces the fixed-point format to be used.
My test program:
int main(array<System::String^>^ args)
{
double d = 0.00006;
Debug::WriteLine(d.ToString("f")); // Uses the default precision value, 2
Debug::WriteLine(d.ToString("f5"));
Debug::WriteLine(d.ToString("f9"));
Debug::WriteLine(d.ToString("f99")); // Highest supported
return 0;
}
Result:
0.00
0.00006
0.000060000
0.000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Related

Saving float and double precision in C++ during cin/cout and scanf/printf

I want to read floats and doubles from standart input and save its precision (exact the same digits after floating point) and be able to output (cout/printf) as it is. What the most convinient (and simplest way) to do this?
Thanks!
float f;
cin >> f;
cout << f;
Use setprecision.
Here is the solution
cout<<setprecision(the precision you want to set here)<<variablename;
eg. If you want to set precision of the output to 5 for variable var use it like this:
cout<<setprecision(5)<<var;
setprecision is a manipulator. Learn more about manipulators here.
It sets the decimal precision to be used to
format floating-point values on output operations.
Behaves as if member precision were called with n as argument on the
stream on which it is inserted/extracted as a manipulator (it can be
inserted/extracted on input streams or output streams).
This is a manipulator and is declared in header <iomanip>
Since the input has an unknown precision, the simplest method is to read them as strings, not doubles/floats.
If you need the float value, a simple string to double conversion is needed.
Any other method will probably fail since you rely on imperfect conversion from string to float done by the standard library.
The latter can't distinguish between 0.4 and 0.40.

Converting int to double screws up the decimal point

In the debug window, when I input this command:
po 1912/10.0
The output is 191.19999999999999.
What I really want to get back is 191.2.
Why is this happening, and how can I convert an int into a double with precision?
From What Every Programmer Should Know About Floating-Point Arithmetic:
Why don’t my numbers, like 0.1 + 0.2 add up to a nice round 0.3, and instead I get a weird result like 0.30000000000000004?
Because internally, computers use a format (binary floating-point) that cannot accurately represent a number like 0.1, 0.2 or 0.3 at all.
When the code is compiled or interpreted, your “0.1” is already rounded to the nearest number in that format, which results in a small rounding error even before the calculation happens.
This is why programmers say you should only ever store money as an integer. For example int cents = 1995; rather than float dollars = 19.95.
If your app doesn't need to be 100% precise (for example, if you're calculating screen coordinates or translucency or a color) just format your float rounded to 1 or 2 decimal places:
double someValue = 1912/10.0;
NSLog(#"2 decimals: %.2f", someValue);
NSLog(#"0 decimals: %.0f", someValue);
This code will output:
2 decimals: 191.20
0 decimals: 191
That's normal for a floating point number. Double is obviously just an extended precision floating point number. If you want to keep the pristine decimal digits, then don't allow any float/double conversion. Instead store the result as a scaled integer (in your case 1912) and place the decimal manually.
Let me try to explain this another way. When you express a number with a fractional part with a float or double, precision is most often lost. There's no way around that. If you store 1912 as a float and store 10 as a float then divide the first stored value by the second, the value will NEVER be 191.2. That's just the way floating point numbers work. If you look at the number in a debugger you'll see something like 191.19999999999999 as you describe. This, in itself, is an approximation as the value should be 191.19999999999999... but of course you can't even type all the digits in the decimal value of that stored result as the number of digits approaches infinity.
If you're going to use floating point, that's what you'll get. No way around it.
If you really want to get 191.2, then you can't use floating point, at least without doing rounding. Instead, you need to normalize the numbers by just storing the value as 1912 and printing the value with a decimal point to the left of the 2.
There's another brief online description at http://floating-point-gui.de/basic/

Objective C, division between floats not giving an exact answer

Right now I have a line of code like this:
float x = (([self.machine micSensitivity] - 0.0075f) / 0.00025f);
Where [self.machine micSensitivity] is a float containing the value 0.010000
So,
0.01 - 0.0075 = 0.0025
0.0025 / 0.00025 = 10.0
But in this case, it keeps returning 9.999999
I'm assuming there's some kind of rounding error but I can't seem to find a clean way of fixing it. micSensitivity is incremented/decremented by 0.00025 and that formula is meant to return a clean integer value for the user to reference so I'd rather get the programming right than just adding 0.000000000001.
Thanks.
that formula is meant to return a clean integer value for the user to reference
If that is really important to you, then why do you not multiply all the numbers in this story by 10000, coerce to int, and do integer arithmetic?
Or, if you know that the answer is arbitrarily close to an integer, round to that integer and present it.
Floating-point arithmetic is binary, not decimal. It will almost always give rounding errors. You need to take that into account. "float" has about six digit precision. "double" has about 15 digits precision. You throw away nine digits precision for no reason.
Now think: What do you want to display? What do you want to display if the result of your calculation is 9.999999999? What would you want to display if the result is 9.538105712?
None of the numbers in your question, except 10.0, can be exactly represented in a float or a double on iOS. If you want to do float math with those numbers, you will have rounding errors.
You can round your result to the nearest integer easily enough:
float x = rintf((self.machine.micSensitivity - 0.0075f) / 0.00025f);
Or you can just multiply all your numbers, including the allowed values of micSensitivity, by 4000 (which is 1/0.00025), and thus work entirely with integers.
Or you can change the allowed values of micSensitivity so that its increment is a fraction whose denominator is a power of 2. For example, if you use an increment of 0.000244140625 (which is 2-12), and change 0.0075 to 0.00732421875 (which is 30 * 2-12), you should get exact results, as long as your micSensitivity is within the range ±4096 (since 4096 is 212 and a float has 24 bits of significand).
The code you have posted is correct and functioning properly. This is a known side effect of using floating point arithmetic. See the wiki on floating point accuracy problems for a dull explanation as to why.
There are several ways to work around the problem depending on what you need to use the number for.
If you need to compare two floats, then most everything works OK: less than and greater than do what you would expect. The only trouble is testing if two floats are equal.
// If x and y are within a very small number from each other then they are equal.
if (fabs(x - y) < verySmallNumber) { // verySmallNumber is usually called epsilon.
// x and y are equal (or at least close enough)
}
If you want to print a float, then you can specify a precision to round to.
// Get a string of the x rounded to five digits of precision.
NSString *xAsAString = [NSString stringWithFormat:#"%.5f", x];
9.999999 is equal 10. there is prove:
9.999999 = x then 10x = 99.999999 then 10x-x = 9x = 90 then x = 10

Objective C float is not showing all decimals

I'm passing a float to a method but it's not showing all decimals. I have no idea why this is happening.
Here's an example:
[[LocationApiCliente sharedInstance] nearPlacesUsingLatitude:-58.3645248331830402 andLongitude:-34.6030467894227982];
Then:
- (BOOL)nearPlacesUsingLatitude:(double)latitude andLongitude:(double) longitude {
NSString *urlWithCoords = [NSString stringWithFormat:#"%#&lat=%f&long=%f", CountriesPath, latitude, longitude];
Printing urlWithCoords will result in:
format=json&lat=-58.364525&long=-34.603047
More of this. What I'm getting from the output terminal:
(lldb) p -3.13419834918349f
(float) $4 = -3.1342
(lldb) p -3.13419834918349
(double) $5 = -3.1342
Any ideas?
Change the %fs in your formatting strings to specify the desired number of decimals, e.g., %.16f.
Note that the number of decimals shown does not guarantee that they are correct, but at least they won't be truncated.
Overall the problem is that floating point numbers do not contain information about the precision, and cannot precisely represent some decimal values, so formatting can not in the general case “autodetect” the number of decimals. So you just need to override the default by specifying the desired number and accept that it's not representative of location accuracy. But since you seem to be passing the floats to another program via the URL, this shouldn't be a problem—a larger number of decimals is better.
It looks like CoreLocation uses doubles to represent degrees, so I'd be surprised if there's any more geographic precision to be found on the device.
But, in general, if you want to represent higher precision than double, you can use long double in Objective-C like this...
long double myPi = 3.141592653589793;
NSLog(#"%16.16Lf", myPi);

Having a hard time working with floats

I wasn't really sure what to name the title.
I'm checking to see if the value of two floats are the same. If I use printf() or NSLog(), the values return 0.750000. However, a line like if (value1 == value2) { return TRUE; } doesn't work. I can assume that in reality, the floats are beyond the 7 decimal places, and printf() / NSLog() can't return a value beyond 7 decimals.
I tried googling a way to see how I could cut down a float to a smaller amount of decimal places, or simply convert it to another data type, but I didn't get such luck so far.
You might want to peek at float.h (http://www.gnu.org/software/libc/manual/html_node/Floating-Point-Parameters.html) for a non-arbitrary definition of epsilon. In particular, FLT_EPSILON and FLT_DIG.
You can decide of an epsilon that is the maximum value under which number are equals. Like
#define EPSILON 0.0001
if (fabs(floatA - floatB) < EPSILON) { retun TRUE; }
fabs(x) returns the absolute value of the double x.
You may also want to use the double instead of float data type (double is twice the size of a float).
When ever you compare floating point numbers you need to use a tolerance:
if (Abs(value1 - value2) < epsilon)
{
}
where epsilon is a value such as 0.000001