【问题标题】:How to check that multiplication of two decimal numbers is greater than ULONG_MAX?如何检查两个十进制数的乘积是否大于 ULONG_MAX?
【发布时间】:2021-05-17 08:32:16
【问题描述】:

如果两个数字的乘积大于 ULONG_MAX 限制,我需要编写一个返回 true 的函数。否则返回 false

我尝试了以下方法:

bool isGtThanULONG_MAX(double A, double B) {
    double result = A * B;
    if (result > ULONG_MAX)
        return true;
    else
    {
        //If this could be due to overflow, then again check:
        double temp = result / A;
        
        if (A != 0 && (temp != B)) {
        // overflow handling
        return true;
    }
    return false;
}

}

输出: 以下 cout 语句中的第 1 行和第 4 行给出了 OVERFLOW(这显然是错误的输出),其余的给出了 NO-OVERFLOW(这是正确的)输出。 为什么它失败了?我错过了什么吗?请帮忙。

    cout << (isGtThanULONG_MAX(10, 0.0000000000000000001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;//OVERFLOW
    cout << (isGtThanULONG_MAX(10, 0.000000000000000001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 0.00000000000000001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 0.0000000000000001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;//OVERFLOW
    cout << (isGtThanULONG_MAX(10, 0.000000000000001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 0.00000000000001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 0.0000000000001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 0.000000000001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 0.00000000001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 0.0000000001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 0.000000001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 0.00000001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 0.0000001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 0.000001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 0.00001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 0.0001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 0.001) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 0.01) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 0.1) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;
    cout << (isGtThanULONG_MAX(10, 1) == true ? "OVERFLOW" : "NO-OVERFLOW") << endl;

PS - 我在 Windows 上的 MS Visual Studio Professional 2015 上试用了这个程序。

【问题讨论】:

  • 我查看了链接的问题,但它们描述了两个整数的乘法。我的案例也涉及十进制数。请查看 cout 语句 #1 和 #4。我需要知道他们为什么失败?请回答。此问题与任何问题均不重复。
  • 嗨,@πάντα ῥεῖ,我只需要知道为什么 #1 和 #4 cout 语句会失败。在这方面你能帮我吗?
  • 使用调试器,单步执行程序,看看自己。
  • 这不是将无符号类型作为参数的问题的重复。请不要急于结束重复的问题。谢谢。
  • 请注意,double 或任何 IEEE 754 表示通常不是精确数字。大多数时候它是一个近似值。

标签: c++ c


【解决方案1】:

如果ULONG_MAX 不能完全表示为double,则会出现问题。例如,如果类型 double 使用 IEEE 表示并且 long 有 64 位,则在隐式转换为 double 类型以进行比较时,ULONG_MAX 将四舍五入到 2 的下一个幂。因此,如果发生这种情况,比较应该是 result &gt;= ULONG_MAX 以确保 isGtThanULONG_MAX(0x1p32, 0x1p32) 返回 true,而不是仅适用于 32 位 long 的 &gt;

#include <float.h>
#include <limits.h>
#include <stdbool.h>

bool isGtThanULONG_MAX(double A, double B) {
    double result = A * B;
    if (ULONG_MAX + 1.0 == ULONG_MAX)
        return result >= ULONG_MAX;
    else
        return result > ULONG_MAX;
}

【讨论】:

  • 希望你不介意我的编辑。投赞成票。
  • 具有 64 位长整数和 64 位 IEEE 双精度数,(double)ULONG_MAX == (double)ULONG_MAX + 1
  • 确定吗?试试 65536 * 65535.99999。
  • @n.'pronouns'm。感谢您指出这个问题。我使用由编译器优化的溢出显式测试更新了解决方案。
  • @chqrlie:我不明白这个条件“如果(ULONG_MAX + 1.0 == ULONG_MAX)”。你能告诉我,在 if 条件中,A & B 控件的哪些值会进入?
猜你喜欢
  • 1970-01-01
  • 2018-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多