MIRACL用户手册(译) 联系客服

发布时间 : 星期六 文章MIRACL用户手册(译)更新完毕开始阅读d542f2ed0975f46527d3e1dc

对mirsys的调用还会初始化MIRACL包集成的错误跟踪系统。Whenever an error is detected the sequence of routine calls down to the routine which generated the error is reported, as well as the error itself。一条典型的错误消息类似:

MIRACL error from routine powltr

called from isprime called from your program Raising integer to a negative power

这些错误报告能够协助我们在开发过程中更方便地调试这些例程。一个相关的实例变量是TRACER,初始为OFF,若设置为ON,将导致对MIRACL例程中的程序流程的跟踪输出到屏幕上。

实例标记ERNUM初始为0,用于记录最近发生的MIRACL发生的错误的编号。如果标记ERCON设置为FALSE(默认),错误消息将直接输出到stdout并通过系统调用exit(0)终止进程。如果你的系统不支持exit例程,则编程人员必须提供一个替代品。若ERCOM设置为TRUE,则不会发出错误消息,取而代之由编程人员来负责检查和处理错误。在这种情况下,程序将继续执行。编程人员可以选择处理错误并将ERNUM重围为0。但错误经常是致命的,如果ERNUM非零,接下来的所有MIRACL例程调用都将“失败(fall-through)”并立即退出。可能的错误列表请参见miracl.h。

用户程序中的每个big或flash变量都通过调用mirvar初始化,它也允许对变量赋一个整数作为初值。 miracl.h中声明的所有的算术和数论例程均在在这些变量上使用。这些例程在参数使用上(几乎总是)具有完全的灵活性。例如调用multiply(x,y,z)将把x和y的乘积保存到z中,调用multiply(x,y,x)、multiply(y,y,x)或multiply(x,x,x)都是同样有效的。请注意按照约定第一个参数通常是例程的输入。

所提供的例程不仅可以用于对big和flash进行算术运算,也可以在内置的整形和双精度浮点型变量上进行运算。

类型转换例程也有提供,细节请参考参考手册中的有关文档。

输入输入到文件或I/O设备由例程innum,otnum,cinnum,cotnum处理。前两个使用mirsys中指定的固定基数。后两者与可由用户动态更改的实例变量IOBASE联合使用。一个简单的规则是若程序是CPU边界

的(原文:A simple rule is that if the program is CPU bound),或涉及基数的变动,则初始应将基数设置为MAXBASE(或0——当完全宽度的基数可行时),并使用cinnum和cotnum。另一方面,如果程序是I/O边界的(原文:If the program is I/O bound),或需要访问数字中的特定位(通过getdig,putdig和numdig),则使用innum和otnum。

例程instr,otstr,cinstr和cotstr以类似的方式支持从字符串输入或输出到字符串。输入例程可用于为big或flash设置一大的常量值。通过输出到字符串,可在实际输出文件或I/O设备之前完成格式化。

最大可表示基数为256的值,基数小于等于60的数使用0-9,A-Z以及a-z中的符号。

64进制数字强制使用base64编码。如有必要,base64数字输出时将在结尾后以 ‘=’符号填充(不会有其它格式)。输入时,空白字符会被跳过,并忽略填充部分。不要对flash数字使用base64。不要使用base64输出负数(会忽略符号)。

如果基数大于64且不等于64,则将使用ASCII码0-255。

基数256在将一行文件当作大整数来解析时有用,如在第8章描述的公钥加密程序中。例程big_to_bytes和bytes_to_big允许直接在内部的big格式和二进制之间进行转换。

字符串通常是以零结尾的。但在使用基数256时会产生一个问题。在这种情况下0-255中的任何一个数字都可出现在一个数中,所以零不应当作字符串的终止符。输入时应采用别的方式来指定字符串中数字的数量。

通过在调用innum或instr之前设置实例变量INPLEN(例如置为25),输入将在送入25个字符后终止。INPLEN初始为0,并且每次相关操作都会在返回之前将它重置为0。

例如,先初始化一个使用400字节长的big变量的MIRACL实例: miracl *mip = mirsys(400,256); 使用此基数,内部计算将非常高效。

将一个ASCII字符串作为一个256进制数输入,它以0结尾,因为不需要INPLEN: innum(x, stdin);

现在再输入一个1024位的随机值: mip->INPLEN=128;

innum(y, stdin); 以16进制查看输出: mip->IOBASE = 16; cotnum(w, stdout); 以64进制查看输出: mip->IOBASE = 64; cotnum(w, stdout);

有理数可以使用小数点形式(例如0.3333)或分数形式(例如1/3)来输入。也可以通过设备实例变量RPOINT为ON或OFF来选择以哪一个形式输出。

第四章 内部表示

大部分语言的编译器通常提供一到两种浮点类型用于表达所有实数,与一到多种整数类型一起用来描述所有数字。这些内置数据类型与底层的计算机架构密切相关,它们通常合理地设计为对出现频率更高的较小数运算得更快,而不是与那些出现频率领很低的大数字一样慢。浮点类型允许使用相对来说小范围的二进制数字(例如32位)来以足够的精度在一个大的动态范围内表示实数。整数类型直接使用相同的二进制值来表示一个限值内的所有整数,或用二进制补码来表示负数。

传统的计算机运算方式存在几个缺陷:

1. 浮点和整数类型是不相容的。整数集虽然是无穷的,但依然是有理数的一个子集,而有理数则是实数的一个子集。因此每个整数都有一个等价的浮点表示。不幸的是这两种表示通常是不一样的。例如整数类型会用等价的二进制来表示一个小的正整数,而浮点类型则会用分开的尾数和幂来表示。这意味着需要用转换程序来从一种形式转换为另一种形式。

2. 大部分有理数都无法被精确的表示(例如1/3,译注:貌似1/3是无理数啊)。事实上浮点系统只能精确地表示那些分母是底层表示的基数的因子的整数倍的有理数。例如我们熟悉的十进制系统只能精确地表示分母是2或5的倍数的有理数;1/20是0.05,而1/21是0.0476190476190...

3. 浮点的圆整是依赖于基数的,而且也是不明显的错误的一个根源。

4. 一个事实是整数和浮点数据类型的尺寸由计算机架构决定,这使语言设计者难以保持它们的语言能够真正可移植。

5. 数字只能以固定的依赖机器的精度来表示。在许多应用程序中这是严重的缺陷,例如在新兴的正在成长的公钥加密算法领域。

6. 基数依赖的现象是不易考虑的。例如很难从传统的整形中访问十进制数的某一位。

这里描述了一组用于直接操作多倍精度有理数的C例程,多倍精度整数是其一个兼容子集。同时也可以进行近似的实数运算。

两个新的数据类型是big和flash。前者用于存储多倍精度整数,后者以\不固定斜杠)的形式用分子和分母来存储小数。两者的格式都是一个固定长度的数字数组,外加一个包含符号和长度信息的独立32位整数。

需要用一种内置类型来储存数字,这个类型定义为mr_small,它可以是int、long甚至double。 struct bigtype {

mr_unsign32 L; mr_small *d; };

typedef struct bigtype *big; typedef struct bigtype *flash; 定义变量:

big x, y[10], z[10][10];

要注意一个big变量仅仅是一个指针,big(或flash)变量实体所需要的内存是从堆(也可以从栈)中分配的。因此使用前必须进行初始化。