本帖最后由 riyad 于 2025-3-25 02:43 编辑 $ B& c! [) b7 a- k9 o2 n. y" V
% p6 C7 Q. a8 H4 ?( VTON 智能合约中的算术运算始终使用整数,从不使用浮点数,因为浮点数是不可预测的。 因此,重点应放在整数及其处理上。 Int 是一个 257 位的有符号整数类型。 它能够存储 −2256−2256 和 2256−12256−1 之间的整数。 " W- }% S0 Z4 D6 [# k
表示法 Tact 支持多种方式编写 Int 的原始值作为整数字面量。
0 [5 ^7 r' C: L0 T8 w大多数符号允许在数字之间添加下划线 (_),但下列符号除外:
J+ w- T; p' ~/ `0 l, c
- 字符串表示法,如 NanoToncoins 案例所示。
- 带前导零的十进制数 00。一般不鼓励使用,参见 下文。
! b. L4 a8 _! h5 ^: R3 ~5 v
& E4 {: N0 R5 t5 P+ y& ]7 y$ I# F9 N $ W7 X7 A5 G" c Y. e* _* T
3 l5 X$ V" C' }# e% e- v/ G# o# I6 q2 D& x9 Y6 x e
此外,不允许在 4__24__2 中连续使用多个下划线,或在 42_42_ 中使用尾部下划线。
2 d8 q1 P, g/ h. y: \/ _9 d% k! X6 B. l1 L. N5 l
! X% j6 w: ^) P# P
十进制最常见、最常用的数字表示方法,使用十进制数字系统: 123456789123456789。% p' `9 H# D+ P/ d' ^" p7 B
您可以使用下划线(_)来提高可读性: 123_456_789123_456_789 等于 123456789123456789。 或者,您也可以在数字前加上一个 00,这样就禁止使用下划线,只允许使用十进制数字:0123=123.0123=123. 注意,强烈建议使用这种带前导零的符号,因为可能会与 TypeScript 中的八进制整数字面混淆,而 TypeScript 通常与 Tact 一起用于开发和测试合约。4 A3 M+ ~9 d8 W
1 t1 c3 D0 k4 v十六进制使用十六进制数字系统表示数字,用 0x0x(或 0X0X)前缀表示:0xFFFFFFFFF0xFFFFFFFFF。 使用下划线(_)提高可读性:0xFFF_FFFF_FFF0xFFF_FFFF_FFF 等于 0xFFFFFFFFF0xFFFFFFFFF。 八进制使用八进制数字系统表示数字,用 0o0o(或 0O0O)前缀表示:0o7777777770o777777777。 使用下划线(_)提高可读性:0o777_777_7770o777_777_777 等于 0o7777777770o777777777。 二进制使用二进制数字系统表示数字,用 0b0b(或 0B0B)前缀表示:0b1111111110b111111111。 使用下划线(_)提高可读性:0b111_111_1110b111_111_111 等于 0b1111111110b111111111。 NanoToncoins与美元的运算要求小数点后保留两位小数——这些用于表示美分(cents)的值。 但是,如果我们只能用整数来表示数字 $1.251.25 ,我们该如何表示呢? 解决的办法是直接使用 cents。 这样, $1.251.25 就变成了 125125 美分。 我们只需记住最右边的两位数代表小数点后的数字。 同样,在使用 TON 区块链的主要货币 Toncoin 时,需要九位小数,而不是两位小数。 可以说,nanoToncoin是Toncoin的 1109th1091th。 因此, 1.251.25 Toncoin 的数量,可以用 Tact 表示为 ton("1.25"),实际上就是数字 12500000001250000000。 我们称这样的数字为_nanoToncoin(s)(或_nano-ton(s))而不是_美分。 序列化将 Int 值编码为持久状态(contracts 和 traits 的字段)时,通常最好使用比 257257-bits 更小的表示形式,以降低存储成本。 这些表示法的使用也被称为 “序列化”,因为它们代表了 TON 区块链运行的本地TL-B类型。 持久状态大小在状态变量的每个声明中都会在 as关键字后指定: - contract SerializationExample {
9 O& Z; s' z, A4 V B - // persistent state variables
/ O3 t% u9 r7 H# e) n6 ~; S: N/ A ]; V - oneByte: Int as int8 = 0; // ranges from -128 to 127 (takes 8 bit = 1 byte)0 e, d x/ {2 R3 A! L
- twoBytes: Int as int16; // ranges from -32,768 to 32,767 (takes 16 bit = 2 bytes)
4 o5 l8 L3 ]3 i6 b9 }" T6 E
+ j" ~0 j% X! P7 M/ f- q2 \- init() {
) q. X" l+ c* M2 n h/ i' r - // needs to be initialized in the init() because it doesn't have the default value
1 Z: b7 g( T; k% ?$ x6 \1 t6 H3 r" k - self.twoBytes = 55*55;
. D; }; w, m5 `: `- v - }
. A9 p% Z4 S7 v! P& q - }
复制代码 4 Q5 m. s: `# k2 q: W) l2 i
整数序列化也适用于 Structs 和 Messages 的字段,以及 maps 的键/值类型: 2 D" D- ^: O$ V" H5 q4 D3 d5 }- S- U
- struct StSerialization {
3 }! @ B; g/ P4 _ - martin: Int as int8; [0 y! V) V# d: R
- }8 u$ y+ X* ?' ?/ O& B$ ]
- * w* g' L8 g5 n; k V1 z
- message MsgSerialization {
$ Y; O n/ Z. q9 G# I8 ` - seamus: Int as int8;
% K1 Y) X9 m% |$ F/ P) V; x$ S - mcFly: map<Int as int8, Int as int8>;9 `2 A, |* k- ~% O! r$ P; i3 F
- }
复制代码动机很简单: - 在状态中存储 10001000 个 257257 位的整数成本大约为每年 0.1840.184 TON。
- 相比之下,存储 10001000 3232-bit 整数每年只需花费 0.0230.023 ton 。+ X: l; r6 t# M9 L
8 i8 p( Z# T2 t9 P) t" F( E$ f8 O7 n, C4 w
1 b& ]' c; F7 N. v
6 b% K$ p1 ^: Y8 q |