【问题标题】:Why bool is not represented using float?为什么 bool 不使用浮点数表示?
【发布时间】:2012-10-12 04:10:05
【问题描述】:

在 C(C99 之前)中,布尔值通常表示为

typedef int bool;
#define true 1
#define false 0

为什么它被表示为'int'而不是'float'?

这是一个面试题,我什至想知道为什么会问这样的问题! 有什么令人信服的答案吗?

【问题讨论】:

  • 浮点数大于 int ...
  • 您为什么希望将其表示为浮点数?浮点运算比较慢,对于只有两个值的类型使用浮点是完全没有意义的。
  • 在大多数机器上,floats 的大小与ints 相同
  • @Taiki:至少在 x86 和 ARM 中,sizeof(float) = sizeof(int) = 4。
  • 现在是“大多数机器”,但公平地说,回到 70 年代或 80 年代,当公约成立时,sizeof(float) == 4; sizeof(int) == 2; 很常见。除了intfloat 更可取的所有其他原因,这还不错,但它不能解释为什么不使用char

标签: c types boolean


【解决方案1】:

这是一个坏主意的原因有很多。但是没有这样做的原因,即没有这样做的历史原因是,早期的计算机没有浮点单元(并且在更长的一段时间内,有些计算机有一个和一些没有)。

【讨论】:

    【解决方案2】:

    bool 值主要用于比较,使用int 类型使用integer ALU 进行这些比较。它非常快,因为它在 CPU 的正常管道中。如果要使用float 类型,则必须使用浮点单元,这将花费更多周期。

    另外,如果您想支持在数学表达式中使用 bool 类型,即:

    x = (4 * !!bool1) + (2 * !bool1);
    

    为了避免不必要的分支,使用整数 ALU 也会比使用浮点单元更快。

    上面的代码等价于下面的分支代码:

    if (bool1) {
       x = 4;
    } else {
       x = 2;
    }
    

    【讨论】:

    • 我建议用(4 * !!bool) 替换(4 * bool)。希望您知道原因。
    • 旧处理器就是这种情况,现代处理器没有不同的单元
    • 使用 x86,您仍然需要将两个参数压入 fpu 堆栈,然后发出 fcomi 指令:stackoverflow.com/a/7057771/33263
    • @K.Brafford 如果bool 是整数类型,这意味着如果bool1 为真,4 * bool1 可能会溢出,从而导致未定义的行为。
    • 也就是说,如果 bool 是一个整数类型,其值为 0 或 1,因为它只是从逻辑表达式的结果中赋值,那么就不可能溢出。所以这取决于你的价值观的来源。添加!! 会做额外的工作来验证输入。出于优化目的,何时可以/应该删除此类工作,每个人可能都有不同的看法,但是如果您正在编写巧妙的代码以避免分支,并且您信任源的价值,然后我会说把它排除在外。
    【解决方案3】:

    C 的 _Bool/bool(和 C++ 的 bool)应该是一种非常简单的数字类型,并且表现得像一个数字类型,你无法得到比 charint 这样的更简单的类型。

    int 是出于性能或历史原因的典型选择。

    替换float 会限制它。您将无法使用<<>> 移动float

    您有时希望能够移动运算符的结果,例如&&||==!=><>=<=、@ 987654339@,在 C++ 中是 bool 类型,在 C 中伪装成 _Bool/bool(隐式转换为 int)。

    【讨论】:

    • 你会通过移动布尔值来实现什么。我想不出一个完成或需要移动布尔值的情况
    • 好吧!!!不要这么快下结论。我说我没有在“BOOLS”中看到>。在整数上,它被广泛使用......再次阅读
    • @ManikSidana:如果你想用布尔值查看它,那么对 Alexey 的代码进行非常简单的更改。 bool condition = (y < 0); x |= (condition << 3);。您现在是否对“完成或需要”移动布尔值的情况感到高兴,因此condition 在下面是int 很有用?
    • @WilliamMorris 让我们同意不同意。
    • @Steve Jessop:如果你想固执己见,那我就说同意……我只是陈述了一个简单的观点,不要把它变成争论……
    【解决方案4】:

    由于其他答案提到的许多原因(缓慢、历史等),我想补充一点,通常浮点数存在“准确性”问题(Ref: Wikipedia )。谁希望所有这些问题让计算机说出“真相”或“虚假”?我希望你也不要。选择“不准确”的东西作为“布尔”值是没有意义的。

    【讨论】:

    • 这完全无关紧要。首先,浮点完全能够准确地表示 0 和 1。除非您打算取余弦,否则浮点运算中发生的舍入是无关紧要的。其次,整数也有同样的问题。例如,如果将 7 除以 3,则结果在数学上是不正确的(它是 2,但应该是 2 1/3)。这在使用整数表示布尔值时无关紧要,因为您不会将 true 除以 3 或执行其他不准确的操作。浮点数也是如此。
    • 好的,我们已经知道'int'应该是'boolean'的类型。但我们正在寻找可能不使用“浮动”的原因。也可能有一个假设的原因。但为了准确起见,我们可以保证整数算术会给我们“精确”的结果(我们知道 7/3=2 表示 int)。但是对于浮点数,在很多情况下你不会得到任何“精确”的值。例如,浮点引入了精度,这可能使我们采用“向上取整”值。我不是在争论,我展示了为布尔值选择浮点数的各种阴暗面。
    • 精度不影响对布尔值使用浮点数。这根本无关紧要。使用 0 和 1 表示 false 和 true 将在浮点中工作而不会出现任何错误。您为实现布尔运算而对它们执行的任何浮点运算都不会产生任何不准确性。相等或不等式的测试将正常工作。精度根本没有影响,因此无关紧要。整数也有精度。整数运算在某些运算中也是不精确的。但这并不妨碍它们被用于布尔值。浮点数也是如此。
    • 好的,如果你说'0'和'1'将被用作'0'和'1',那么任何类型都适合。但是在 C 中,您可能希望对布尔结果(可能包括任何算术运算)做很多事情,结果由于浮点舍入,您可能会得出一个“非精确/近似”值。对于浮点运算的所有“最佳案例”(甚至是好的案例),我都接受您的回答。
    猜你喜欢
    • 1970-01-01
    • 2018-04-25
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 2014-09-27
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    相关资源
    最近更新 更多