当数字包含所有 9 作为数字时,查找数字长度的函数返回无效输出

Function that finds length of a number is returning an invalid output when number contains all 9s as digits

我有一个函数 returns 一个数字的长度除以 10 直到它小于 1 并且大于 0

例如

12345 => 5

83 => 2

问题是 999999999999999 的长度应该是 15 但我的函数 returns 16。该功能适用​​于其他一切...

例如

123456789123456 => 15

C代码

#include <cs50.h>
#include <stdio.h>

int find_num_len(float num);
int counter = 0;

int main(void) {

    long long int cc_num;

    do {
        cc_num = get_long_long("Number:");
    }

    while( cc_num < 0);
    find_num_len(cc_num);
}


int find_num_len(float num) {
    if (num > 0 && num < 1) {
      printf("%i\n", counter);
      return counter;
    }

    counter ++;

    find_num_len(num/10);

    return 0;
}

可能是舍入错误。第一个不能用 float 精确表示的整数是 2^24,大约是 1600 万,比连续 15 个 9 小得多。

尝试使用最高可达 2^54 的 double; (从记忆中,最好检查 ieee 754 规范来验证)它可以表示高达 ~1e16 的整数。

或者 - 计算数字的 log10,加一,然后截断。

Len = floor (log10(number) + 1)

您不必要地将 long long int 转换为 float。 IEEE-754 32位float的尾数是24位。并且2^24 = 16777216,这是可以保证精度表示的最大可能数。

这是一种方法:

#include <stdio.h>

int find_num_len(long long int num) {
    return num >= 10 ? 1 + find_num_len(num / 10) : 1;
}

int main(void) {
    printf("%d\n", find_num_len(999999999999999));
    return 0;
}

或者如果你想避免递归:

int find_num_len(long long int num) {
    int count = 1;

    while (num >= 10) {
        num = num / 10;
        count++;
    }

    return count;
}