How to convert a floating point value to an integer with exact precision, for example 123.3443 - 1233443?

Code example:

int main() { float f = 123.542; int i = (int)f; printf("%d\n",i); } 
+7
source share
6 answers

123.3443 cannot be represented exactly with a floating point number - in a 32-bit float, it is actually represented as 16166984 / 131072 , which is actually 123.34429931640625, not 123.3443. (This is about 6.8 x 10 ^ -7.)

If this is really what you want (which probably isn't), look at how the IEEE-754 float works, and pull out your favorite math set with arbitrary precision. Once you understand what is going on behind the scenes, creating an accurate view should not be too complicated. Creating a "close enough" rounded view is actually a lot more complicated. :)

+10
source
 int i = (int) (f * 10000 + 0.5); 
+2
source

Multiply the float by 10^x , where x is the number of digits after the decimal number you want, and then you spell it over int .

0
source

If you don't need to reprocess the converted number and just want to convert the numbers to an integer, the easiest way is to use sprintf and then sum the decimal places with the for loop using the power of 10 rules. If you need "exact accuracy" for math, use a BCD. The following algorithm will allow you to trim the number of digits for "accurate accuracy".

 #include "math.h" long ConvertToScaledInteger (float value, int significantDigits = -1) { // Note: for 32-bit float, use long return and for double use long long. if (significantDigits < 1) // Ditch the '-' and the '.' significantDigits += 2; else ++significantDigits; // Ditch the '.' char* floatingPointString = malloc(sizeof (char) * (4 + FLT_MANT_DIG - FLT_MIN_EXP)); /*< This solution is for a 32-bit floating point number. Replace FLT with DBL, and it will produce the max number of chars in a 64-bit float string. */ if (significantDigits < 0) //< Then use all of the float digits. { sprintf (floatingPointString , "%f", floatingPointNumber); } else //< Then truncate the number of decimal places. { char decimalPlaceString[9]; char percentString = "%\0"; sprintf (decimalPlaceString, "%s%if", percentString , significantDigits); sprintf (floatingPointString , decimalPlaceString, value); } int stringLength = strlen (floatingPointString), index; long returnValue = 0; double powerOfTen = 10.0, currentValue; // Find if we have an ending of .0, and backtrack. if (floatingPointString[stringLength - 1] == '0' && floatingPointString[stringLength - 2] == '.') index = stringLength - 3; else index = stringLength - 1; for (; index > 0; --index) { if (floatingPointString[index] == '.') --index; // Subtract ASCII '0' converts ASCII to integer. currentValue = (double) floatingPointString[index] - '0'; returnValue += (long) currentValue * pow (10.0, powerOfTen); powerOfTen += 1.0; } if (floatingPointString[0] == '-') returnValue *= -1; return returnValue; } 
0
source

Integer equivalent to float f

 float f=123.456; 

can be done using modff() e.g.

 float integral, fractional; char str[50], temp[20]; fractional = modff(f, &integral); 

Now integral has an integer part (for example, 123.000000) and fractional has a fractional part (for example, 0.456000).

If the floating point number ( f in this case) was negative, both integral and fractional would be negative.

You can do

 if(fractional<0) { fractional = -fractional; } 

to fix it.

Now,

 sprintf(temp, "%g", fractional); 

The %g format "0.456" removes trailing zeros, and temp now has "0.456" .

 sprintf(str, "%g%s", integral, temp[1]=='.'?temp+2:""); 

temp[1]=='.'? performed because if the fractional part was 0 , when printing fractional there would be no decimal point, as it would be 0 , not 0.000000 . If the second character in temp not . , fractional is zero, and we do not need to bother him.

Now in our case str will be "123456" . But this is in the form of a string. We need to convert it to an integer. Use strtol() for this.

 long l=strtol(str, NULL, 10); if(l>INT_MAX || errno==ERANGE) { printf("\noverflow"); } else { printf("\n%d", strtol(str, NULL, 10)); } 

You can check the return value of strtol() and the errno value (from errno.h . Check if it is ERANGE ) to see if an overflow has occurred.

To find out if the resulting value can be stored in int , first store the value returned by strtol() in long int , and see if it is larger than INT_MAX (it is in limits.h ).

It should be noted that the accuracy of the result will depend on the accuracy with which the floating point number is presented in binary format.

0
source
 #include <stdio.h> #include <stdlib.h> #include <string.h> int f2i(float v, int size, int fsize){ char *buff, *p; int ret; buff = malloc(sizeof(char)*(size + 2)); sprintf(buff, "%*.*f", size, fsize, v); p = strchr(buff, '.'); while(*p=*(p+1))p++; ret = atoi(buff); free(buff); return ret; } int main(){ float f = 123.3443; printf("%d\n", f2i(f, 7, 4)); f=123.542; printf("%d\n", f2i(f, 6, 3)); return 0; } 
-one
source

All Articles