将浮点数每一位拆分并输出

1.问题

来源 https://ask.csdn.net/questions/7901417

题目要求如下,将浮点数拆分,不允许使用将浮点数整数倍扩大的办法(那样太简单了)

auto-orient1

2.办法

2.1 库函数modf

C语言有一个库函数modf,可以将浮点数的整数部分和小数部分拆分开来、

https://www.runoob.com/cprogramming/c-function-modf.html

1
double modf(double x, double *integer)

其中参数x是原有浮点数,参数integer是输出型参数,会存放x的整数部分。

函数的返回值是x的小数部分

2.2 代码

第一版本代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <cmath>
#include <string.h>
#include <string>

using namespace std;

int main() {
double num;
cin >> num;

double int_part;
double frac_part = modf(num, &int_part);

string int_str = to_string((int)int_part);//获取到整数部分并打印
for (char c : int_str) {
cout << c << " ";
}

cout << ". ";

int i = 0;
int n = 2;//小数点后n位
while (i < n) {
frac_part *= 10;
double int_part;
frac_part = modf(frac_part, &int_part);
cout << (int)int_part << " ";
i++;
}
cout<<endl;

return 0;
}

这样已经做到了将整数和小数部分给分离打印了

2.3 精度缺失问题

但是,测试可以看到,小数的最后一位出现了可能会存在的精度缺失,比如123.22的小数部分变成了21,肯定是不对的。

1
2
3
4
5
6
7
8
9
> ./test
923.97
9 2 3 . 9 7
> ./test
123.22
1 2 3 . 2 1
> ./test
923.90
9 2 3 . 8 9

img

3.解决

所以还需要用另外一个办法来处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <cmath>
#include <string.h>
#include <string>

using namespace std;
//https://ask.csdn.net/questions/7901417
int main() {
double num;
cin >> num;

double int_part;
double frac_part = modf(num, &int_part);
cout << "int_part: "<< int_part <<" | frac_part: " <<frac_part << endl;

char str[10];
sprintf(str, "%.3f", frac_part); //将小数部分打印到字符串中
cout << "str: " << str << endl;

// 打印整数部分
string int_str = to_string((int)int_part);
for (char c : int_str) {
cout << c << " ";
}
cout << ". ";
// 打印小数部分
int n = 2;//小数点后n位
for(int i=0;i<n;i++)
{
// 因为打印到字符串中的数据包含了最开始的0.
// 前两个字符就是0. 应该从第三个字符开始打印
cout << str[2+i] << " ";
}
cout << endl;

return 0;
}

可以看到,问题已解决,符合题目要求!

img