如何计算小数点前后的位数?

How to calculate number of digits before and after decimal point?

今天在我的 c++ class 测试中提出了一个问题。 "Write a program that inputs a floating point number and calculates the number of digits before and after decimal point."

我用这段代码计算了小数点前的数字:

float n;

cin>>n;

float temp = n;

int count = 0;

while(temp1 > 1) {

    count++;

    temp = temp/10;
}

cout<<count;

但我坚持了后面的部分。谁能告诉我该怎么做?或者可以提供整个程序吗?

提前致谢,

Write a program that inputs a floating point number and calculates the number of digits before and after decimal point.

嗯,这个任务要求的是使用 float 和标准 c++ 无法真正解决的问题,因为 float 值指数和尾数的二进制表示未在C++ 标准。
因此,您无法知道将使用多少位数字来表示数字的小数部分,除非您知道 c++ 编译器究竟是如何实现 float(或 double)二进制表示的。

很可能针对目标 CPU 及其处理浮点值的能力优化了实现。


所以你唯一的机会就是将数字读取为第一个 std::string 表示,计算 '.' 字符前后出现的数字,最后转换 std::string 变量为 float 值。


这是我在回答的第一部分中的意思的简单说明:

#include <iostream>
#include <iomanip>
#include <limits>
#include <cmath>
#include <sstream>

int main() {

    std::istringstream iss("3.1415"); // same as reading from cin
    std::cout << "Input: " << iss.str() << std::endl;
    float temp;
    iss >> temp;
    std::cout << "Internal representation: " 
              << std::fixed << std::setprecision(22) << temp << std::endl;
    float fraction = temp - abs(temp);
    int fractiondigits = 0;
    while(fraction > std::numeric_limits<float>::epsilon()) { // epsilon is the smallest 
                                                              // value that can be 
                                                              // represented in binary form
        fraction *= 10.0f;
        fraction -= abs(fraction);
        ++fractiondigits;            
    }
    std::cout << "Number of digits used in the representation: " 
              << fractiondigits << std::endl;
}

输出为

Input: 3.1415
Internal representation: 3.1414999961853027343750
Number of fraction digits used in the representation: 21

Live Demo


所以你看这与用户的输入不一致。

我不知道你的教授是否打算询问并让你承认用户输入和 float 的内部表示的这种不一致。
但如前所述,实际位数取决于编译器实现和平台,因此小数位数没有明确的答案。

这个问题基本上无关紧要。大多数实数都有无限多的数字,但计算机表示的数字必须具有有限的表示形式。对于二进制表示的常见情况,表示的数字也有有限十进制表示。但是,将此十进制表示截断为更少的数字(准确地说是少至 std::numeric_limits<float>::max_digits10)仍然会获得相同的可表示数字。因此,计算机浮点数的相关位数最好是指它们的二进制而不是它们的十进制表示。这是由std::numeric_limits<float>::digits给出的(总计:点前后)。