65.9K
CodeProject 正在变化。 阅读更多。
Home

Lint: 大整数对象库

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.26/5 (9投票s)

2005年12月15日

2分钟阅读

viewsIcon

96897

downloadIcon

436

Lint 是一个带符号的大整数数据类型类库。

引言

Lint 是一个有符号大整数数据类型类库,支持其他固有整数数据类型可用的所有数学运算符。精度不是像其他可用库中那样是任意的。而是,构成 lint 变量的位数取决于头文件中声明的 #define 指令的值。

背景

那么为什么要另一个大整数库呢?有以下几个原因:

  • 我想要一个支持所有可能的重载运算符的类,以便我可以像使用 intlong 这样的固有数据类型一样使用 lint。我能找到的免费实现似乎都不支持所有可重载的运算符。
  • 我想要一个专门为 Visual C++ 和基于 IA-32 的 PC 架构创建的类。我不想要一个为了跨编译器和跨平台兼容性而牺牲执行速度的库。我想要一个可以用内联汇编代码优化的库。
  • 我想要一个方法尽可能快速和高效的类。 任意精度逻辑和浮点逻辑会带来性能损失。 这个库是高效的,因为精度不是任意的,并且所有操作都严格基于整数。 这样,鉴于已知的数据类型和大小,我可以编写高度优化的汇编例程。

Using the Code

一旦你在你的源代码中包含了头文件,使用 lint 就类似于在 C++ 中使用任何其他数字数据类型。 少数值得注意的例外是在声明、赋值和输出中。

#include "lint.h"
#include <stdio.h>

int main() {
    // value assignment of a literal
    lint a = 1234;
    // a lint is a signed integer data type
    lint b = -5678;
    // assignment to another lint value
    lint c = a;
    // use a string for those really BIG numbers
    lint d = "457639857304951675093650987359087";
    // this works for negative values too
    lint e = "-563857365015613047563";
    
    lint x, y, z;
    // math shouldn't be a problem.
    x = d*e+a*b;
    y = x/(e*e);
    
    // assignment to zero is the only ambiguous
    // operation that you need to be specific on.
    z = (signed long)0;                                

    // the class allocates its own buffer
    // to print a character representation of its value.
    // By default, it prints in base 10
    printf( "y base 10 = %s\n", z.value() );
    
    // You can print in another radix though - anything from 2 to 36
    printf( "y base 16 = %s\n", z.value(16) );
    printf( "y base 2 = %s\n", z.value(2) );
    
    // Internally, the memory for a lint is laid out
    // going from MSB to LSB in an array of 32-bit DWORDs.
    // [2047th bit ... 1024th bit ... 0th bit]
    
    // If you need more or less than 2048 bit numbers, open lint.h
    // and redefine LINT_LENGTH
    
    // Lastly, the function call operator allows direct
    // referential access to the DWORDs that comprise
    // a lint value.
    // This sets the Most Significant DWORD to 0x12345678
    y(0) = 0x12345678;
    // LAST_DWORD is a constant defined in the header file
    long my_bit_field = y(LAST_DWORD);
    
    return 0;
}

关注点

实现条件测试确实很麻烦。 我的实现有效,但我认为必须有一种更好的方法来做到这一点。 还有其他我想对库做的事情。

  • 可能使用 FFT、Barrett 或其他算法实现更快的乘法和除法算法
  • 添加使用任何从 2 到 36 的基数的 string 来赋值的功能,而不仅仅是 10 进制
  • 使用 MMX 和 XMM 寄存器来实现更快的内联汇编

历史

首次发布 2005年12月4日 作者:Jeremy A. Wilson  
更新 2005年12月6日 作者:Jeremy A. Wilson 发现我的比较运算符使用了错误的汇编指令,如果 MSB 在一个 DWORD 中设置而不在另一个中设置,则无法正确报告。
更新 2005年12月9日 作者:Jeremy A. Wilson 在进一步审查我 12 月 6 的修复之后,我意识到我仍然没有正确修复它。 现在我有了。 我还运行了一套完整的比较。

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.