为什么大多数计算机编程语言不允许像十进制或十六进制那样使用二进制数?
- 在 VB.NET 中,你可以写一个像 &H4 这样的十六进制数
- 在 C 中,您可以编写一个十六进制数,例如 0x04
为什么不允许二进制数?
- &B010101
- 0y1010
奖励积分!... 哪些语言允许二进制数?
编辑
哇!- 所以大多数人认为这是因为简洁和糟糕的旧“波浪”认为这是由于二进制表示的技术方面。
为什么大多数计算机编程语言不允许像十进制或十六进制那样使用二进制数?
为什么不允许二进制数?
奖励积分!... 哪些语言允许二进制数?
编辑
哇!- 所以大多数人认为这是因为简洁和糟糕的旧“波浪”认为这是由于二进制表示的技术方面。
因为十六进制(很少是八进制)文字更紧凑,使用它们的人通常可以比破译二进制数更快地在十六进制和二进制之间进行转换。
Python 2.6+允许使用二进制文字,Ruby 和Java 7也是如此,您可以使用下划线使字节边界变得明显。例如,十六进制值0x1b2a
现在可以写为0b00011011_00101010
.
在具有用户定义文字的 C++0x中将支持二进制数,我不确定它是否会成为标准的一部分,但最坏的情况是您可以自己启用它
int operator "" _B(int i);
assert( 1010_B == 10);
为了使位表示有意义,您需要知道如何解释它。您需要指定您正在使用的二进制数的类型(有符号/无符号、二进制恭维、一个恭维、有符号幅度)。
我曾经使用过的唯一正确支持二进制数的语言是硬件描述语言(Verilog、VHDL 等)。对于如何处理以二进制输入的数字,它们都有严格的(并且经常令人困惑)定义。
NAME
perlnumber - semantics of numbers and numeric operations in Perl
SYNOPSIS
$n = 1234; # decimal integer
$n = 0b1110011; # binary integer
$n = 01234; # octal integer
$n = 0x1234; # hexadecimal integer
$n = 12.34e-56; # exponential notation
$n = "-12.34e56"; # number specified as a string
$n = "1234"; # number specified as a string
有点离题,但较新版本的 GCC 添加了允许二进制文字的 C 扩展。因此,如果您只使用 GCC 进行编译,则可以使用它们。文档在这里。
Common Lisp 允许使用二进制数,使用 #b...(位从 2 的最高到最低的幂)。大多数情况下,使用十六进制数字至少同样方便(通过使用#x...),因为在您的脑海中转换十六进制数字和二进制数字相当容易。
虽然 C 仅支持以 8、10 或 16 为基数,但实际上编写一个预处理器宏并不难,它使编写 8 位二进制数变得非常简单和易读:
#define BIN(d7,d6,d5,d4, d3,d2,d1,d0) \
( \
((d7)<<7) + ((d6)<<6) + ((d5)<<5) + ((d4)<<4) + \
((d3)<<3) + ((d2)<<2) + ((d1)<<1) + ((d0)<<0) \
)
int my_mask = BIN(1,1,1,0, 0,0,0,0);
这也可以用于 C++。
十六进制和八进制只是编写二进制的较短方法。您真的想要在您的代码中定义一个 64 字符长的常量吗?
普遍的看法认为,长的二进制数字字符串,例如一个 int 的 32 位,对于人们来说很难方便地解析和操作。十六进制通常被认为更容易,尽管我使用的任何一种都不足以形成偏好。
如前所述,Ruby 试图通过允许将 _ 自由插入到文字中来解决此问题,例如:
irb(main):005:0> 1111_0111_1111_1111_0011_1100
=> 111101111111111100111100
D 支持使用语法 0[bB][01]+ 的二进制文字,例如 0b1001。它还允许在数字文字中嵌入 _ 字符,以便更轻松地阅读它们。
Java 7 现在支持二进制文字。所以你可以简单地写0b110101。关于此功能的文档不多。我能找到的唯一参考是here。
记录在案,并回答这个问题:
奖励积分!... 哪些语言允许二进制数?
Specman (aka e) 允许二进制数。虽然老实说,它并不是一种通用语言。
在 Smalltalk 中,它就像 2r1010。您可以使用最多 36 个左右的任何基数。
十六进制不那么冗长,并且可以表达二进制数可以表达的任何内容。
如果你真的想要,Ruby 对二进制数有很好的支持。0b11011 等
从可读性和可用性的角度来看,十六进制表示似乎是定义二进制数的更好方法。他们不添加它的事实可能更多的是用户需要技术限制。
我希望语言设计者只是没有看到足够的需要添加二进制数。在处理标志或位掩码时,普通编码器可以解析十六进制和二进制。一些语言支持二进制表示,这很好,但我认为平均而言它很少使用。虽然二进制——如果在 C、C++、Java、C# 中可用,可能会比八进制使用更多!
在 Pop-11 中,您可以使用由数字(2 到 32)+ 冒号组成的前缀来表示基数,例如
2:11111111 = 255
3:11111111 = 3280
16:11111111 = 286331153
31:11111111 = 28429701248
32:11111111 = 35468117025
尽管它不是直接的,但大多数语言也可以解析字符串。Java可以通过方法将“10101000”转换为int。
并不是说这是有效的或任何东西......只是说它在那里。如果它是在静态初始化块中完成的,它甚至可能在编译时完成,具体取决于编译器。
如果您擅长二进制,即使数字很短,也很容易将 0x3c 视为 4 个 1 后跟 2 个零,而即使二进制中的那个短数字也是 0b111100 ,这可能会让您的眼睛在确定之前受伤的数量。
0xff9f 正好是 4+4+1 个,2 个 0 和 5 个 1(看起来位掩码很明显)。试图数出 0b1111111110011111 更令人恼火。
我认为问题可能在于语言设计者总是在十六进制/八进制/二进制/其他方面投入巨资,并且只是这样想。如果您经验不足,我完全可以看到这些转换不会那么明显。
嘿,这让我想起了我在考虑基本转换时想到的一些东西。一个序列——我认为没有人能找出“下一个数字”,但一个人确实做到了,所以它是可以解决的。试试看:
10
11
12
13
14
15
16
21
23
31
111
?
编辑:顺便说一句,这个序列可以通过将序列号输入到大多数语言的单个内置函数中来创建(当然是 Java)。
Forth 总是允许使用任意基数的数量(当然要达到 CPU 的大小限制)。想要使用二进制:2 BASE !
八进制:8 BASE !
等。想要使用时间?60 BASE !
这些示例都是从基组输入到十进制的 10。要更改基数,您必须代表当前数字基数所需的基数。如果在二进制中并且您想切换回十进制,那么1010 BASE !
将起作用。大多数 Forth 实现都有“词”来转换到公共基础,例如DECIMAL
、HEX
、OCTAL
和BINARY
。