数字与小数

129 阅读6分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第40天,点击查看活动详情

数字

  • 它可以包含从09的十进制数字,并且必须至少包含这些数字字符中的一个。它可以包含前加零或尾随零。
///  d ##Class(YX.FouthDataType).Number()
ClassMethod Number()
{

	s number = 000012314805
	w number,!
}
  • 它可以包含任意顺序的任意数量的前导加号和减号。但是,加号或减号不能出现在除“E”科学记数法字符之外的任何其他字符之后。
	s number = 1E2
	w number,!
	s number = 1E+3
	w number,!
	
	s number = 1E-4
	w number,!
	s number = -1E-5
	w number,!
  • 使用当前区域设置的PlusSignMinusSign属性值来确定这些符号字符,这些符号字符取决于区域设置。要确定区域设置的PlusSignMinusSign字符,请调用GetFormatItem()方法。
	w ##class(%SYS.NLS.Format).GetFormatItem("PlusSign"),!
	w ##class(%SYS.NLS.Format).GetFormatItem("MinusSign"),!
  • 小数分隔符的选择取决于区域设置:美国格式使用句点(.)。作为小数分隔符,这是默认设置。欧洲格式使用逗号()作为小数分隔符。若要确定区域设置的DecimalSeparator字符,请调用GetFormatItem()方法.
    w ##class(%SYS.NLS.Format).GetFormatItem("DecimalSeparator")
  • Caché将数字转换为规范形式时,会将所有前导零和尾随零都将被删除。这包括从分数中删除整数零。
	w 0.660000
  • 使用可以$FNUMBER$JUSTIFY函数将去掉0的小数恢复。
	w $fn(.6, "N", 1),!
	w $justify(.6, "", 1),!
  • 对于所有数值运算,包含规范形式的数字的字符串在功能上与相应的数字相同。
	w "3" = 3,!
	w "-2.5" = -2.5,!

(-0不是规范数字。)

  • 对于算术运算,仅包含非规范形式的数字字符的字符串在功能上与相应的数字相同。
	w "003" + 3 = 6,!
	w "++-2.5000" + - 2.5 = -5,!
  • 对于大于/小于运算,仅包含非规范形式的数字字符的字符串在功能上与相应的数字相同。
	w "003" > 2,!
	w "++-2.5000" >= -2.5,!
  • 混合数字字符串是以数字字符开头,后跟一个或多个非数字字符的字符串。数值和布尔运算(等式运算除外)通常将此字符串解析为具有数值0,直到它们遇到非数字字符。此时,字符串的其余部分将被忽略。
	w "31 yaoxin" + 2,!   
	w "+31/7" + 2,!     
	w "31,000" + 2,!      
	w "31.0.99" + 2,!   
	w "31.5.99" + 2,!
  • 非数字字符串是在遇到数字字符之前遇到非数字字符的任何字符串。空格被视为非数字字符。数值和布尔运算通常将此字符串解析为具有数值0
	w +"8" = 8,!         
	w +"+00008" = 8,!        
	w +"8 star" = 8,!   
	w +"star" = 0,!    
	w +"" = 0,!
  • 可以使用连接运算符(_)将一个数字连接到另一个数字。Caché首先将每个数字转换为其规范形式,然后对结果执行字符串连接。
	w 12 _ 34,! 
	w 12 _ +34,! 
	w 12 _ --34,! 
	w 12.0 _ 34,! 
	w 12 _0034.0,! 
	w 12E0 _ 34,!

小数

Caché支持小数的两种不同表示形式:

  • 默认情况下,Caché使用自己的浮点标准decimal number表示小数。它提供最高级别的精度-18位十进制数字。
	w 1/1.5,!
	w $decimal(1/1.5),!
	w $decimal("NAN"),!
	w $decimal("INF"),!
  • IEEE双精度浮点标准是表示小数的行业标准方式。IEEE浮点数使用二进制表示法进行编码。它的精度为53个二进制位,相当于15.95个十进制数字的精度。支持特殊值INF(无穷大)和NaN(非数字)
	w $double(1/1.5),!
	w $double("NAN"),!
	w $double("INF"),!
  • 可以精确表示的最大整数是19位整数-92233720368547758089223372036854775807。这是因为这些是可以用64个带符号位表示的最大数字。
	s maxNum = 9223372036854775807
	w maxNum,!
	s plus1 = maxNum + 1
 	w plus1,!
  • 由于这种四舍五入,产生大于这些19位整数的数字的算术运算将其低位数字替换为零。
 	w (plus1 + 17) = (plus1 + 21),!
  • 除了19位的舍入之外,大于308或309位的整数还会导致<MAXNUMBER>错误。取整行为也会在146或147位发生变化,具体取决于整数。
/// d ##class(YX.FouthDataType).GetExtremelyLargeNumbersLevel()
ClassMethod GetExtremelyNumbers()
{
	try {
		s num = 1
		for i = 1 : 1 : 310 {
			s num = num_1 
			w i + 1," 数字 = ", +num,! 
		}
	}
	catch exp { 
		w "异常类型: ",exp.Name,!
		w "位置: ",exp.Location,!
		w "代码: " ,exp.Code,!
		w "数据: ",exp.Data,! 
		ret
	}
}
2 数字 = 11
3 数字 = 111
...
19 数字 = 1111111111111111111
20 数字 = 11111111111111111110
...
146 数字 = 11111111111111111110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
147 数字 = 111111111111111101270000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
...
309 数字 = 111111111111111116760000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
310 数字 = 异常类型: <MAXNUMBER>
位置: zGetExtremelyLargeNumbersLevel+5^YX.FouthDataType.1
代码: 1
数据: