如何将浮点数的精确小数部分作为整数获取?

7
我正在尝试从浮点数中提取精确的小数部分。我尝试使用以下代码:
float f=254.73;

int integer = (int)f;
float fractional = f-integer;

printf ("The fractional part is: %f", fractional);

但输出结果是:0.729996。因此,当我进行以下操作时:
float f=254.73;

int integer = (int)f;
float fractional = f-integer;
int fractional_part_in_integer = ((int)(f*100)%100);

printf ("The value is: %d", fractional_part_in_integer);

它输出了72,但是我想从给定的数字254.73中精确地提取73。我已经知道在printf()函数中使用%.2f打印两位小数。但是在我的代码中,我现在不想打印这个数字。我希望把那个小数部分作为整数形式73进行一些计算。

所以,我的问题是如何从254.73中提取小数部分,以便我可以得到73作为整数进行更多的计算?


4
浮点数往往不能以你想要的确切值来表示。你得到的结果是合理的。一个有趣的试验是打印变量 f 的值,它可能只是接近你所想象的值(虽然我自己没有尝试过,所以不确定)。更新:我已经尝试过了:http://ideone.com/9fbeme - mah
谢谢。但是,我希望有一种方法可以对73进行其他计算。更新:是的,我已经这样做了,并得到了你在实验中发现的那个值。 - UkFLSUI
2
由于您的硬件无法准确表示254.73,因此您需要找到其他可以表示的硬件,或者改用基于整数的计算(例如25473之类的),并稍后除以100。 - mah
4
如果你的意思是“如何得到0.73”,那么如果你的硬件无法表示它,你永远不可能得到这个精确的值。但是,你可以将原始值(以及所有其他要处理的值)乘以100,在这个级别上进行处理(表示恰好是你需要的值的100倍),然后再除以100来获得精确的结果(仍然受限于你的硬件能够表示的范围)。 - mah
2
@RakibulIslam 现在我更好地理解了你试图解决的问题,我认为你最好的选择是按照user3121023在他的答案中建议的方式拆分_string_数据。这将给你两个整数值,254和73,然后你可以像你已经在做的那样进行处理。只需将“部分美元”值处理为整数(你预计应该在0到99之间),而不是浮点值即可。 - mah
显示剩余2条评论
4个回答

11
如何将浮点数的精确小数部分提取为整数?
尝试从浮点数中提取精确的小数部分。
使用`modf()`或`modff()`函数。
double modf(double value, double *iptr);
float modff(float value, float *iptr);

modf 函数将参数值分解为整数部分和小数部分,...
C11 §7.12.6.12 2

#include <math.h>

double value = 1.234;
double ipart;
double frac = modf(value, &ipart);

对于OP的需求,可能有一个更好的方法是首先将一个缩放值四舍五入,然后再分解为整数和小数部分。
double value = 254.73;
value = round(value*100.0);
 
double frac = fmod(value, 100);  // fmod computes the floating-point remainder of x/y.
double ipart = (value - frac)/100.0;

printf("%f %f\n", ipart, frac);
254.000000 73.000000

参考细节:当 OP 使用 254.73 时,它会被转换为最接近的 float 值,可能是 254.729995727539...
float f = 254.73;
printf("%.30f\n", f);
// 254.729995727539062500000000000000

2
这样做不会产生与OP已经获得的相同结果吗? - mah
1
@mah。OP的方法在以下情况下会出现问题:1)当f超出int范围时,2)f为负数,3)intf精度低。对于像1.99999这样的值,OP的第二种方法可能会给出不令人满意的结果。 - chux - Reinstate Monica
不考虑检查,只考虑你的推理,我相信你特定的使用情况是使用fmod()建议的有效原因...但是考虑到实际值,即OP正在使用的254.73,除非你的建议解决了他的困境(即:他期望得到0.73而不是0.7299996),否则我认为你的帖子是一个很好的评论,但不是一个答案。不过,我愿意接受被证明我可能是错的。 - mah
@mah ((int)(f*100)%100); 也可能受到接近整数的 f 值的影响,但 (f*100) 计算结果为整数。 - chux - Reinstate Monica
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - chux - Reinstate Monica

2
您可以使用sprintf和sscanf将值打印到字符串中,然后提取小数部分。 %*d扫描并丢弃格式化字符串的第一个整数。扫描点,然后是小数部分。
#include <stdio.h>        

int main( void)           
{                         
    char fp[30];          
    int fraction;         
    float f = 254.73f;    

    sprintf ( fp, "%.2f", f);
    sscanf ( fp, "%*d.%d", &fraction);
    printf ( "%d\n", fraction);

    return 0;                  
}

3
  1. 这种方法仅提取小数部分(根据OP的要求),但对于输入值如123.996,代码将渲染出分数部分为0,不清楚整数部分如何增加到124。
  2. char fp[30]; 可能太小了,建议使用char fp[FLT_MAX_10_EXP + 6];
- chux - Reinstate Monica

0

最简单的方法是使用标准库函数<math.h>中的ceil
float254.73可以转换为254.7299957275390625000000
f-integer将给出0.7299957275390625000000
现在将其乘以100并使用ceil函数得到不小于72.99957275390625000000的最小整数值。

int fractional_part_in_integer = ((int)ceil(fractional*100)) % 100;

更新:正如@Sneftel评论中指出的那样,本答案中建议的方法不会始终有效。

一个简单的技巧是使用math.h中的round函数来四舍五入f,然后提取小数部分。

float f=254.73;

int int_part = (int)f;
float fractional = round(f*100)/100 - int_part;
int fractional_part_in_integer = (int)(fractional*100);

printf("%d, %d\n ", int_part, fractional_part_in_integer);

输出:

254, 73

1
ceil 函数的签名为 double ceil(double x);。它计算不小于 x 的最小整数值并返回 ⎡x⎤。不要忘记包含 #include <math.h> - haccks
1
ceil()函数同样有可能得到一个偏差为1的数字。 - Sneftel
@Sneftel;我想你说的是 floor。顺便说一下,这是我的解决方案的演示 - haccks
3
@haccks 嗯?试试这个吧。无论是 ceil 还是 floor 都不能有效地工作,因为该值既有可能略低于0.01的倍数,也有可能略高于它。 - Sneftel
3
你是对的,我更新了我的回答。现在已经修复了。 - haccks

-2

使用内置函数find()查找字符串中点"."的位置。

#include <iostream>
using namespace std;

int main()
{    
    string f = "254.7356656";    
    int position = f.find(".");    
    cout << f.substr(position + 1);    
    return 0;    
}

输出:7356656


在 Stack Overflow 的答案中推荐使用 #include <bits/stdc++.h> 会引来负评;请使用必需的标准头文件。参见:https://dev59.com/R1wZ5IYBdhLWcg3wIdR7 - Adrian Mole

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接