什么32位编译器下操作64位及128位运算?是的你没有听错。
寄存器不支持,算法来解决。
只要了解二进制的算法机制,我们甚至还可以扩展出256位甚至更高位的运算。
闲话不说,直接上代码:
这里只探讨无符号整数型数据的存储及运算,其他类型运算大家可以自行脑洞。
一、首先先演示数据类型的转换及存储
1、数据类型定义
'======================
' 数据类型定义
'======================
' 64位
'----------------------
TYPE uint64
low AS DWORD
high AS DWORD
END TYPE
'----------------------
' 128位
'----------------------
TYPE uint128
low AS uint64
high AS uint64
END TYPE
'----------------------
' 256位 这个与上同理
'----------------------
TYPE uint256
low AS uint128
high AS uint128
END TYPE
2、读取新定义的数据类型中的数据值,其中包括了数值提取算法
'=======================================================
' 64位 ULONG高低位数值合并算法
'=======================================================
FUNCTION Mak_ULong(BYVAL value AS uint64) AS STRING
FUNCTION = FORMAT$(value.high*(2^32)+value.low,"#")
END FUNCTION
'=======================================================
' 128位 ULONGLONG高低位数值合并算法
'=======================================================
FUNCTION Mak_ULongLong(BYVAL value AS uint128) AS STRING
FUNCTION = FORMAT$((value.high.high*(2^32)+value.high.low)*(2^64)+(value.low.high*(2^32)+value.low.low),"#")
END FUNCTION
3、代码测试
LOCAL c1 AS uint64
LOCAL a2 AS QUAD
a2 = 3245646757657861
MEMORY COPY VARPTR(a2), VARPTR(c1), SIZEOF(a2)
MSGBOX Mak_ULong(c1)
LOCAL c1 AS uint128
LOCAL a2 AS QUAD
a2 = 3245646757657861780
MEMORY COPY VARPTR(a2), VARPTR(c1), SIZEOF(a2)
MSGBOX "c1=" + Mak_ULongLong(c1)
总结:
由上测试结果来看,算法可以正确提取到自定义类型中的数据值。
由于PB对于字符串转换的精度限制最大18位,所以在测试中未使用极限的数据进行测试,不过这个可以用FreeBasic写个字符串转换的库函数来实现。毕竟FB是一个64位的编译器。
至于自定义数据类型的数学运算,将有空在下篇笔记中再演示了。
算法模型:
(高位数)*(2)^(总位数/2)+ 低位数 (由于高低位总是字节对齐的,所以可以除2)。
等价于将高位数左移32位或64位,然后加上低位数,即求得真实数据值。