I want to convert float to int removing decimal point, meaning if F = 2.521, conversion to int = 2521 What is the fast way to do this using C++?
Asked
Active
Viewed 1,172 times
0
-
5`round(F * 1000.0)`. Note with `float F = 2.521;` , `F` is not _exactly_ 2.521. – chux - Reinstate Monica Jul 05 '21 at 02:34
-
2Use strings. For the good fraction of floating point numbers, they cant be represented exactly: https://stackoverflow.com/questions/588004/is-floating-point-math-broken – NathanOliver Jul 05 '21 at 02:34
-
Further to the what chux said above, the rounding modes are: std::ceil, std::floor, std::trunc, or std::round. round is the most common, but might not be exactly what you need. – robthebloke Jul 05 '21 at 02:35
-
1What's the source of these floats? Should `2.5` be mapped to `25` and `2.52` mapped to `252`? If so you might run into some precision issues where things that have a short exact representation in decimal _don't_ have one in binary. – Nathan Pierson Jul 05 '21 at 02:37
-
Hmm, strings are probably slow, but I like rounding method. – G.Azma Jul 05 '21 at 02:38
-
I want floats to be mapped to it's lowest decimal (not counting super low floating point errors) – G.Azma Jul 05 '21 at 02:38
-
Strings are slow... sometimes. Depends a lot on what you're going to do with them. I find that unless I'm doing arithmetic with numbers, strings work faster and easier. – user4581301 Jul 05 '21 at 02:43
-
@G.Azma: When you say "mapped to lowest decimal" do you mean "rounded towards negative infinity" (e.g. -5.250000000001 becomes -526) or "rounded towards zero" (e.g. -5.250000000001 becomes -525) or do you mean "not rounded in the first place" (e.g. -5.250000000001 becomes -5250000000001)? – Brendan Jul 05 '21 at 02:47
-
@G.Azma What if the value was 2.520999908447265625? This is a value `float` can exactly encode. Would you want `2520999908447265625` to print out as the integer or `2521` or `2520` or ??? – chux - Reinstate Monica Jul 05 '21 at 02:47
-
I want 2.515715 to print out 2515715, but 1.15151519581011 not, it's too low – G.Azma Jul 05 '21 at 02:52
-
@G.Azma A `float` cannot encode 2.515715. The nearest `float` is 2.5157148838043212890625. What should that print out? – chux - Reinstate Monica Jul 05 '21 at 02:55
-
Sorry, I am not familiar with how floats work, comment about rounding answered my question, I wanted to map float to int from start to end (8 decimal places, or something reasonable like that, so I can just multiply float by 1e8) – G.Azma Jul 05 '21 at 02:58
-
1@G.Azma: Do you mean "no more than 8 fractional digits" (e.g. 123456789123456789.0 becomes 123456789123456789) or do you mean "no more than 8 significant digits (e.g. 123456789123456789.0 becomes 12345678)? Note that the former may cause problems with overflowing the resulting integer. – Brendan Jul 05 '21 at 03:00
-
8 significant digits – G.Azma Jul 05 '21 at 03:02
3 Answers
0
I have no idea if it's the fastest way (or merely "a way"), and haven't tested if it behaves as I intend (especially with regard to precision loss), but here's my attempt at "extract up to 8 significant decimal digits from float into integer, with trailing zero suppression and rounding towards zero"):
#include <math.h>
int32_t convert(float value) {
double v = value; // Need to increase size to reduce risk of precision loss
int sign = 0;
int32_t result = 0;
int digit;
// Extract sign and ensure v isn't negative
if(v < 0) {
sign = 1;
v = -v;
}
// Reduce magnitude of v by dividing by 10 until it's between 0.0 and 1.0 (exclusive).
while(v >= 100000000.0) {
v /= 1000000000.0;
}
if(v >= 10000.0) {
v /= 100000.0;
}
if(v >= 100.0) {
v /= 1000.0;
}
if(v >= 10.0) {
v /= 100.0;
} else if(v >= 1.0) {
v /= 10.0;
}
// Extract (up to) 8 significant digits from v while trying to avoid trailing zeros (e.g. the original value 1.2 would hopefully become 12 and not 12000000).
for(int i = 0; (i < 8) && ((float)v > 0.0); i++) {
digit = floor(v * 10);
result = result*10 + digit;
v = v * 10 - digit;
}
// Suppress any trailing zeros that slipped through due to precision losses
while( (result != 0) && (result % 10 == 0) ) {
result /= 10;
}
// Restore the original value's sign
if(sign != 0) {
result = -result;
}
// Done!
return result;
}

Brendan
- 35,656
- 2
- 39
- 66
0
i did this with string input of float number.put the string chars into integer array except '.' and then convert integer array into decimal number in base 10.
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
int main()
{
string str="";
cout<<"Enter num ?\n";
cin>>str;
int k = str.length()-1;
int *a = new int[k];
int x=0;
for(int i=0;i<str.length();i++)
{
if(str[i]!='.')
a[x++] = (int(str[i]))-48;
}
long int res=0;
x=0;
for(int i=0;i<k;i++)
{
res+=a[k-1-i]*pow(10,x++);
}
cout<<"Integer is = "<<res<<endl;
}

Salar Ashgi
- 128
- 2
- 13
-
`int *a = new int[k]` instead of `std::vector`, and no `delete[]` - this is not exactly a good example of C++ in the 21st century. – MSalters Jul 05 '21 at 09:28
0
for (; std::trunc(f) != f; f *= 10);
std::intmax_t const i(f);
Note, that there may still be UB as the range of floats is very large and you obviously need a signed integral type. Note that floats are usually not decimal.

user1095108
- 14,119
- 9
- 58
- 116