数字中间为什么不能插入空格或逗号?编程语言标识符为什么不能以数字开头?哪些编程语言支持数值中插入分隔符更容易看清楚?数据的二进制形式?Decimal类型?不同语言的不同进制字面量?

目录

数字中间为什么不能插入空格或逗号?

编程语言标识符为什么不能以数字开头?

 哪些编程语言支持数值中插入分隔符更容易看清楚?

下划线分隔符

数据的二进制形式

整数

补码

浮点数IEEE754标准

特例

Decimal类型

Decimal计算速度

不同语言的不同进制字面量

字面量包含非法字符


数字中间为什么不能插入空格或逗号?

整数10000不能写成10 000或者10,000, 原因在于为了简化编译器parser字面量的复杂度。一个标准的编译器词法分析器遇到数值类型会不断获取数字并累积,一旦遇到非数字就会退出。如果允许数字中间加空格或者逗号,词法分析器将更复杂,也容易破坏已有语言的结构,产生冲突。当然,一些高级语言为了提升长数值可读性,可以允许数字中间加入一些分隔符:

  • Python (>=3.6版本)可以在数字中间加下划线
    number = 1_000_000
  • Swift可以在整数、浮点数中间加下划线增强可读性
    let number = 1_000_000.000_001

编程语言标识符为什么不能以数字开头?

一个普世原则,数字开头的Token代表数值,不管是十进制、八进制还是十六进制(0x开头)。当然,不以数字开头就被认为是普通标识符。这种简单的约定,方便了编译器词法分析的难度,程序员也很容易理解。

 哪些编程语言支持数值中插入分隔符更容易看清楚?

除了C/ObjC不支持,C++/Java/C#/JS/Swift/VB.NET/Rust/Go/Python 3.6/仓颉 等语言均支持,分隔符一般选择是下划线_, 也有选择用单引号。

  • C++:C++14标准引入了对数字字面量中使用单引号'做分隔支持。
    当然,用-std=c++11会出现build错误。
  • C#:从C# 7.0开始,可以使用下划线在数字字面量中增加可读性。
    可通过编译选项/langversion:6.0确认此功能在7.0以上才会支持:error CS8059: 功能“数字分隔符”在 C# 6 中不可用,请使用 7.0 或更高的语言版本。
    C# 7.2开始支持十六进制数值和二进制数值(0x开头和0b开头)在0x和0b后面插入下划线。
  • Java:从Java 7开始,Java支持在数字字面量中使用下划线。
    反向验证,可通过 -target 1.6 -source 1.6选项确认数字字面量存在下划线有编译错误。
  • JavaScript 从 ES2021 版本开始支持在数值字面量中使用下划线作为分隔符。
  • VB.NET之前不支持,VB.NET最新版已经支持数值中用下划线分隔。例如:
    Dim a as Integer = 1_000
  • Rust/Swift/Go语言都支持数值中用下划线分隔。
  • Python 3.6开始也支持数值用下划线分隔,具体参考:PEP 515 – Underscores in Numeric Literals.
  • 仓颉 支持用下划线在数值字面量中,不论是整型还是浮点型。
    例如1_23代表123,1.2_3代表1.23.

下划线分隔符

你可能会困惑,C#也允许数值中有多个连续的下划线,其实本质上,编译器在解析数值字面量直接忽略下划线,所以多个连续下划线不影响解析,例如 1__200.

  • 需要注意,下划线不能在字面量开头或者结尾。

数据的二进制形式

研究数据的二进制形式可深入理解计算机如何存储数据,以此可以优化、改进甚至创造新的存储方法。

整数

有符号数和无符号数看起来是两种数,其实计算机根本不知道它们的区别。CPU只知道二进制位,你说当有符号数那就是有符号数,你说是无符号数就是无符号数。有人会问,那为什么用int或者unsigned计算从来没出错过?CPU应该了解的呀! 事实是,CPU确实不了解,它只是简单的按照类似1+1=0(进位)这种计算方式计算而已。为了给程序员更多计算结果信息,寄存器记录了数据计算之后的状态位,例如溢出位、符号位、Zero位等等,服务于je/jne等汇编指令做跳转判断。

  • -1有符号整数是UINT_MAX.

补码

整数一般按照补码存储,它有效地解决了符号位和数值大小都存在的“变量空间压缩”功能。即,将符号位至于整数二进制最高位,其余保存数值大小的相对信息。

  • C/ObjC/C++/Java/C#/Pascal 等。

浮点数IEEE754标准

大部分编程语言浮点数遵循此标准。

  • C/ObjC/C++/Java/C#/Pascal 等。

特例

  • JS的Number类型属于特例,所有的数字类型,无论是整数还是浮点数,都是按照IEEE 754标准以双精度64位浮点格式存储的。

Decimal类型

decimal中文为十进制和小数。C#、VB.NET和SQL语言都有定义Decimal类型,主要目的为了表示带小数点的数值更精确,一般存储超过double的8个字节,用16字节。具体存储结构内部,会采用单独存储整数值、符号位和小数部分,具体取决于实现。

  • C# decimal是128位十进制浮点数,有效数字在28位左右,后缀是m或者M.

Decimal计算速度

  • 因为Decimal保存相对复杂,计算速度比普通浮点数要慢。

哪些编程语言在用Decimal类型?

不同语言的不同进制字面量

常见的是十进制,另外为了方便不同场景下使用,八进制和十六进制可以更好的表达二进制,也被大部分编程语言支持,二进制字面量支持程度差异较大。一般而言,0开头(数值位不止一个0)或者0o/0O为八进制,0x或0X开头为十六进制, 二进制如下:

Swift/Ruby/Perl/Rust/Go/Kotlin默认支持0b开头的二进制表示法,除此之外:

  • C/ObjC没有默认二进制的表示方法,0开头是八进制,0x/0X开头十六进制。
  • C++11之前(不包含),和C/ObjC类似,C++11之后,支持0b或0B二进制表示法。
  • Python 2.6开始支持0b或0B的二进制表示法。
  • C# 7.0 开始支持0b或0B的二进制表示法。
  • Java 7 开始支持0b或0B的二进制表示法。
  • PHP 5.4 开始支持0b或0B的二进制表示法。
  • JS ES6+支持0b或0B开头的二进制表示法。
  • Swift支持2、8、10、16四种进制。0b开头为二进制,0o开头为八进制,0x开头为十六进制。
  • VB十六进制是以&H或&h开头,八进制以&O开头,而非其他语言的0x或0开头。

字面量包含非法字符

一般一个八进制字面量中包含超过8的数字,显然是不合法的。编译器默认的行为就提示错误。

  • GCC对于八进制字面量 019 会提示:error: invalid digit "9" in octal constant

不过也存在特例:

  • JS以0开头(不是0x)的字面量会当做八进制,但是如果数字有超过7且在十进制范围,不会当做错误,而是被二次解析为十进制。
    029是十进制的29.


若文章对您有帮助,欢迎关注 程序员小迷 。助您在编程路上越走越好!

微风不燥,阳光正好,你就像风一样经过这里,愿你停留的片刻温暖舒心。

我是 程序员小迷 (致力于C、C++、C#、Android、iOS、Java、Kotlin、Objective-C、Swift、Shell、JavaScript、TypeScript、Python等编程技术的技巧经验分享),若作品对您有帮助,请关注、分享、点赞、收藏、在看、喜欢,您的支持是我们为您提供帮助的最大动力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值