2 ##########################################################################
7 # IeeeCC754 or IEEE 754 Compliance Checker is a precision and range #
8 # independent tool to test whether an implementation of #
9 # floating-point arithmetic (in hardware or software) is compliant #
10 # with the principles of the IEEE 754-854 floating-point standards. #
11 # You can find out more about the testing tool IeeeCC754 at #
13 # http://win-www.uia.ac.be/u/cant/ieeecc754.html #
15 # This tool is in parts based on and greatly benefited from the #
16 # the program FPTEST developed by Jerome Coonen. For a full #
17 # description of the extensions to FPTEST and a reference to #
18 # the original Coonen program, please refer to the URL given above. #
19 # For the options available with the program IeeeCC754 and its #
20 # compatibility with David Hough's hexadecimal UCB format, we #
21 # also refer to the file readme.usage. #
23 # Usage: see readme.usage #
25 # Responsible authors: #
30 # Tarun Agarwal(05-07/2002) #
31 # Johan Bogo (1998-1999) #
32 # Tim Gevers (10-12/2000) #
33 # Debby Ooms (1996-1997) #
34 # Geert Vermuyten (1996-1997) #
35 # Dennis Verschaeren (09/1996-06/2000) #
37 # Copyright (C) 2000 University of Antwerp #
39 # This program can be obtained from the authors, free, but WITHOUT ANY #
40 # WARRANTY; without even the implied warranty of MERCHANTABILITY or #
41 # FITNESS FOR A PARTICULAR PURPOSE. #
44 # Brigitte.Verdonk@uia.ua.ac.be #
45 # Department of Mathematics and Computer Science #
46 # University of Antwerp (UIA) #
47 # Universiteitsplein 1 #
48 # B2610 Antwerp, BELGIUM #
50 ##########################################################################
60 #include <Bitstring.h>
63 /*class implementation*/
65 /***********************************************************************
66 * Member: GetPattern(unsigned long res)
67 * Purpose: returns a Bitstring with the first "res" bits set.
68 * Return: Bitstring with first "res" bits set.
69 ***********************************************************************/
70 unsigned long Bitstring::GetPattern(unsigned long rest)
72 unsigned long pattern =(unsigned long) ((unsigned long) 1 << lengthT) -1;
73 pattern = pattern >> ((lengthT) -rest);
78 /***********************************************************************
80 * Purpose: returns the first block of bitstr. Its only defined to be used
81 * in PutByte so the ^= operator would work.
82 * Return: first block of bitstr -> bitstr[0].
83 ***********************************************************************/
84 unsigned long Bitstring::Convert()
91 /***********************************************************************
92 * Member: Bitstring() Constructor
93 * Purpose: Create empty bitstring
95 ***********************************************************************/
96 Bitstring::Bitstring()
99 lengthT = sizeof(unsigned long)*8;
103 /***********************************************************************
104 * Member: Bitstring(unsigned long size) Constructor
105 * Purpose: Create bitstring of size "size" and initiate it with zeros
107 ***********************************************************************/
108 Bitstring::Bitstring(unsigned long size)
112 lengthT = sizeof(unsigned long )*8;
113 if (size % lengthT == 0)
114 lengthBlock = (size /lengthT);
116 lengthBlock= (size /lengthT) + 1;
117 bitstr = new unsigned long [lengthBlock];
118 for (i=0;i<lengthBlock;i++)
122 /***********************************************************************
123 * Member: Bitstring(char * str) Constructor
124 * Purpose: Create bitstring with "str" as initiale value
126 ***********************************************************************/
127 Bitstring::Bitstring(char * str)
132 length = strlen(str);
133 lengthT =sizeof(unsigned long )*8;
135 if (length % lengthT == 0)
136 lengthBlock = (length /lengthT);
138 lengthBlock= (length /lengthT) + 1;
140 bitstr = new unsigned long [lengthBlock];
142 for (i=0;i<lengthBlock;i++)
145 for (i= length -1; i >= 0; i--)
148 bitstr [(length -1 -i)/lengthT] |= 1 << ((length-1 -i)%lengthT);
152 /***********************************************************************
153 * Member: Bitstring(Bitstring & copy) Copy constructor
154 * Purpose: Create a bitstring with initiale value the bitstring "copy"
156 ***********************************************************************/
157 Bitstring::Bitstring(const Bitstring & copy)
159 length = copy.length;
160 lengthT = copy.lengthT;
161 lengthBlock = copy.lengthBlock;
163 bitstr = new unsigned long [lengthBlock];
164 for (int i=0 ; i< lengthBlock; i++)
165 bitstr[i]= copy.bitstr[i];
172 /***********************************************************************
173 * Member: ~Bitstring() Deconstructor
174 * Purpose: Remove bitstr from memory
176 ***********************************************************************/
177 Bitstring::~Bitstring()
182 /***********************************************************************
184 * Purpose: Get the length of the bitstring
185 * Return: Length of bitstring
186 ***********************************************************************/
187 unsigned long Bitstring::Length() const
192 /***********************************************************************
193 * Member: Resize (unsigned long len)
194 * Purpose: Change the length of the bitstring to "len". If "len" is
195 * larger then the length, the bitstring is appended with 0, else
196 * the bitstring is truncated to the new length "len"
197 * Return: Previous length
198 ***********************************************************************/
199 unsigned long Bitstring::Resize(unsigned long len)
201 unsigned long * temp;
202 long tmplenBlock,tmpMinlen,i,rest,prevLen;
206 /*create bitstr with new size*/
207 if (len % lengthT == 0)
208 tmplenBlock = (len /lengthT);
210 tmplenBlock= (len /lengthT) + 1;
212 temp = new unsigned long [tmplenBlock];
214 /*get length to copy*/
215 if (lengthBlock <= tmplenBlock)
216 tmpMinlen = lengthBlock;
218 tmpMinlen = tmplenBlock;
221 for (i=0; i < tmpMinlen; i++)
222 temp[i] = bitstr[i] ;
225 /*delete old bitstr*/
229 if (len % lengthT != 0) {
230 rest = len % lengthT;
231 value = GetPattern (rest);
232 temp[len/lengthT] &= value;
236 if(lengthBlock < tmplenBlock)
238 for (i = lengthBlock; i < tmplenBlock; i++)
246 lengthBlock=tmplenBlock;
249 length=lengthBlock=0;
250 lengthT = sizeof(unsigned long)*8;
257 /***********************************************************************
258 * Member: GetBit(unsigned long bit)
259 * Purpose: Get the bit value at position "bit"
260 * Return: 0 <= "bit" < length -> The bit value
262 ***********************************************************************/
263 int Bitstring::GetBit(long bit) const
266 if ((0 <= bit) && (bit < length)) {
267 tmp = bitstr[bit/lengthT];
268 if (tmp & (1L << lengthT - 1 - (bit% lengthT)))
274 /***********************************************************************
275 * Member: PutBit (unsigned long bit, unsigned int bitvalue)
276 * Purpose: Replace the bit value at position "bit" with the new "bitvalue"
277 * Return: Previous bit value
278 ***********************************************************************/
279 int Bitstring::PutBit(unsigned long bit,unsigned int bitvalue)
283 /*get current bit value*/
284 prevBit = GetBit(bit);
285 // cout << "bit = " << bit << " " << bitvalue << endl;
286 // cout << "bitstr = " << bitstr[bit/lengthT] << endl;
288 if (bitstr[bit/lengthT] & (1L << (lengthT - 1 - (bit%lengthT))))
289 bitstr[bit/lengthT] -= (1L << (lengthT - 1 - (bit%lengthT)));
292 bitstr[bit/lengthT] |= (1L << (lengthT - 1 - (bit%lengthT)));
293 // cout << "bitstr = " << bitstr[bit/lengthT] << endl;
297 /***********************************************************************
298 * Member: Set (unsigned long bit)
299 * Purpose: Replace the bit value at position "bit" with the 1
300 * Return: Previous bit value
301 ***********************************************************************/
302 int Bitstring::Set(long bit)
304 return PutBit(bit,1);
306 /***********************************************************************
307 * Member: Clear (unsigned long bit)
308 * Purpose: Replace the bit value at position "bit" with the 0
309 * Return: Previous bit value
310 ***********************************************************************/
311 int Bitstring::Clear(long bit)
313 return PutBit(bit,0);
316 /***********************************************************************
317 * Member: ClearBitString ()
318 * Purpose: Clears the bitstring
319 * Return: Cleared bitstring
320 ***********************************************************************/
321 Bitstring Bitstring::ClearBitString()
324 for (i =0; i< lengthBlock; i++)
330 /***********************************************************************
331 * Member: GetByte (unsigned long byte)
332 * Purpose: Get the byte value at position "byte"
333 * Return: The byte value
334 ***********************************************************************/
335 void Bitstring::GetByte(unsigned long byte, Bitstring sub) const
337 SubBitstring(byte*8,sub);
340 /***********************************************************************
341 * Member: PutByte (unsigned long byte, Bitstring bytevalue)
342 * Purpose: Replace the byte value at position "byte" with the new "bytevalue"
343 * Return: Previous byte value
344 ***********************************************************************/
345 void Bitstring::PutByte(unsigned long byte,Bitstring bytevalue)
349 sizeT=sizeof(unsigned long);
351 // GetByte(byte,prevByte);
352 // prevByte.Resize(lengthT);
353 // bytevalue.Resize(8);
354 // bytevalue.Resize(lengthT);
356 /* replace value by "bytevalue" using xor*/
357 // cout << bitstr << endl;
358 // cout << bytevalue << endl << flush;
359 bitstr[byte/sizeT] ^= (bytevalue.Convert() << ((byte%sizeT)*8));
360 // bitstr[byte/sizeT] ^= (prevByte.Convert() << ((byte%sizeT)*8));
361 // cout << bitstr << endl << flush;
364 /***********************************************************************
366 * Purpose: Increase the bitstring value by 1
367 * Return: Carry after most significant bit
368 ***********************************************************************/
373 while ((i <length) && (GetBit(i)== 1))
385 /***********************************************************************
387 * Purpose: Decrease the bitstring value by 1
388 * Return: 1 -> wrap around (negative)
390 ***********************************************************************/
391 int Bitstring:: Dec()
395 while ((i<length) && (GetBit(i) == 0))
406 /***********************************************************************
407 * Member: BitstrToString()
408 * Purpose: Converts a bitstring to a C-string
409 * Return: length >0 -> The C-string
410 * else -> "Bitstring is empty"
411 ***********************************************************************/
412 void Bitstring::BitstrToString(char str[256]) const
420 /*convert bitstring*/
421 for (i=0; i <length;i++)
425 if ((bitstr[i/lengthT] & block) == 0)
426 str[length-1 -i]='0';
428 str[length-1 -i]='1';
435 // str = new char [25];
436 // strcpy(str,"Bitstring is empty!\n");
442 /***********************************************************************
443 * Member: StringToBitstr(char *str)
444 * Purpose: Converts a C-string to a bitstring
445 * Return: converted bitstring
446 ***********************************************************************/
447 void Bitstring::StringToBitstr(char *str)
452 length = strlen(str);
453 lengthT =sizeof(unsigned long)*8;
454 lengthBlock = (length/lengthT)+1;
457 bitstr = new unsigned long [lengthBlock];
459 for (i=0;i<lengthBlock;i++)
462 for (i= length -1; i >= 0; i--)
465 bitstr [(length -1 -i)/lengthT] |= 1 << ((length-1 -i)%lengthT);
471 /***********************************************************************
472 * Member: Concat(const Bitstring &b2)
473 * Purpose: Puts bitstring *this in front of b2 -> so the first bit of b2
474 * becomes the first bit of *thisb2
475 * Return: *this -> *thisb2
476 ***********************************************************************/
477 void Bitstring::Concat(const Bitstring &b2)
479 Resize(length+b2.length);
480 for (int i = length;i < length + b2.length;i++) {
481 bitstr[i] = b2[i-length];
486 /***********************************************************************
487 * Member: SubBitstring(unsigned long begin, unsigned long count)
488 * Purpose: Returns the substring defined by position "begin" to "count"
489 * Return: substring from bitstring
490 ***********************************************************************/
491 void Bitstring::SubBitstring(unsigned long begin, Bitstring &sub) const
493 Bitstring temp(*this);
495 // cout << "temp = " << temp << endl << flush;
497 // cout << "temp = " << temp << endl << flush;
498 for (i = 0;i < sub.lengthBlock-1;i++)
499 sub.bitstr[i] = temp[i];
500 sub.bitstr[i] = ((temp[i] >> (32 - (sub.length % lengthT))) << (32 - (sub.length % lengthT)));
501 // cout << sub << endl << flush;
504 /***********************************************************************
505 * Member: operator = (const Bitstring ©)
506 * Purpose: Overloads the assign operator. Makes the bistring equal to "copy"
507 * Return: The changed bitstring
508 ***********************************************************************/
509 Bitstring& Bitstring::operator = (const Bitstring ©)
512 // unsigned long * tmp;
515 length = copy.length;
516 lengthT = copy.lengthT;
517 lengthBlock = copy.lengthBlock;
524 //check length of copy
527 bitstr = new unsigned long [lengthBlock];
529 /*copy the bitstring*/
530 for (i=0 ; i< lengthBlock; i++)
531 bitstr[i]= copy.bitstr[i];
542 /***********************************************************************
543 * Member: operator == (const Bitstring & b) const
544 * Purpose: Overloads the equal operator.
547 ***********************************************************************/
548 int Bitstring::operator == (const Bitstring &b) const
552 /*if lengths not equal than the bitstrings not equal */
553 if (length != b.length)
557 while ((i<lengthBlock ) && (value))
559 if (bitstr[i] != b[i])
566 /***********************************************************************
567 * Member: operator != (const Bitstring &b) const
568 * Purpose: Overloads the not equal operator.
569 * Return: not equal -> 1
571 ***********************************************************************/
572 int Bitstring::operator != (const Bitstring &b) const
577 if (length != b.length) {
580 while ((i<lengthBlock ) && (!value))
582 if (bitstr[i] != b[i]) {
588 // cout << *this << endl;
589 // cout << b << endl;
593 /***********************************************************************
594 * Member: operator > (const Bitstring &b) const
595 * Purpose: Overloads the greater than operator.
596 * Return: greater -> 1
598 ***********************************************************************/
599 int Bitstring::operator > (const Bitstring &b) const
607 if (Length() > b.Length())
610 temp.Resize(Length());
613 if (Length() < b.Length())
616 temp.Resize(b.Length());
623 if (GetBit(i)!= b.GetBit(i))
635 /***********************************************************************
636 * Member: operator < (const Bitstring &b) const
637 * Purpose: Overloads the smaller than operator.
638 * Return: smaller -> 1
640 ***********************************************************************/
641 int Bitstring::operator < (const Bitstring &b) const
649 if (Length() > b.Length())
652 temp.Resize(Length());
655 if (Length() < b.Length())
658 temp.Resize(b.Length());
665 if (GetBit(i)!= b.GetBit(i))
679 /***********************************************************************
680 * Member: operator << (unsigned long count)
681 * Purpose: Overloads the shift left operator. Shifts the bitstring "count"
683 * Return: shifted bitstring
684 ***********************************************************************/
685 void Bitstring::operator <<(long count)
689 /*if count > lengthT -> copy blocks*/
690 if ((count/lengthT) > 0)
692 for (j=0; j <lengthBlock ; j++)
694 if (j+(count/lengthT) < (unsigned long)(lengthBlock))
695 bitstr[j]=bitstr[j+(count/lengthT)];
700 //make lastblocks = 0
701 for (j= lengthBlock - (count/lengthT); j < lengthBlock ; j++)
704 /* if count < lengthT -> shift bitwise*/
705 rest = count % lengthT;
707 unsigned long leading = (1L << lengthT-1);
708 for (i=0; i < rest ; i++)
710 for (j=0; j < lengthBlock-1; j++)
714 if (bitstr[j+1] & leading)
717 bitstr[lengthBlock-1] <<=1;
721 /***********************************************************************
722 * Member: operator >> (unsigned long count)
723 * Purpose: Overloads the shift right operator. Shifts the bitstring "count"
725 * Return: shifted bitstring
726 ***********************************************************************/
727 void Bitstring::operator >>(unsigned long count)
729 int i,j, rest,carry = 0;
731 /*if count > lengthT -> copy blocks*/
732 if ((count/lengthT) > 0)
734 // cout << "copy blocks" << endl << flush;
735 for (j=0; j <lengthBlock ; j++)
737 if (j+(count/lengthT) < (unsigned long)(lengthBlock))
738 bitstr[j]=bitstr[j+(count/lengthT)];
743 //make lastblocks = 0
744 for (j= lengthBlock - (count/lengthT); j < lengthBlock ; j++)
750 /* if count < lengthT -> shift bitwise*/
751 rest = count % lengthT;
752 // cout << "rest = " << rest << endl << flush;
753 for (i=0; i < rest; i++)
756 for (j=lengthBlock-1;j > 0; j--)
759 if ((bitstr[j-1] & 1L) == 1L)
760 bitstr[j] |= (1 <<( lengthT-1));
767 /***********************************************************************
768 * Member: operator [] (unsigned long n)
769 * Purpose: Overloads the array operator. Returns/change block "n"
771 ***********************************************************************/
772 unsigned long& Bitstring::operator [](unsigned long n) const
774 //if(( n < 0) || (n > lengthBlock))
778 /***********************************************************************
779 * Member: operator &(const Bitstring &bitst)
780 * Purpose: Overloads the bitwise and operator. Does a bitwise and with
781 * "bitstr" and "bitst". Makes the size of bitst equal to the
783 * Return: bitwised and -> *this & bitst
784 ***********************************************************************/
785 Bitstring Bitstring::operator &(const Bitstring &bitst)
789 Bitstring temp1(*this),temp2(bitst);
791 //make size bitst equal to *this
792 if (lengthBlock > bitst.lengthBlock)
793 temp2.Resize(length);
796 for (i = 0; i<lengthBlock ; i++ )
797 temp1[i] &= temp2[i];
803 /***********************************************************************
804 * Member: operator |(const Bitstring &bitst)
805 * Purpose: Overloads the bitwise or operator. Does a bitwise or with
806 * "bitstr" and "bitst". Makes the size of bitst equal to the
808 * Return: bitwised or -> *this | bitst
809 ***********************************************************************/
810 Bitstring Bitstring::operator |(const Bitstring &bitst)
813 Bitstring temp1(*this),temp2(bitst);
815 //make size bitst equal to *this
816 if (lengthBlock > bitst.lengthBlock)
817 temp2.Resize(length);
820 for (i = 0; i<lengthBlock ; i++ )
821 temp1[i] |= temp2[i];
827 /***********************************************************************
828 * Member: operator ^ (const Bitstring &bitst)
829 * Purpose: Overloads the bitwise xor operator. Does a bitwise xor with
830 * "bitstr" and "bitst". Makes the size of bitst equal to the
832 * Return: bitwised xor -> *this ^ bitst
833 ***********************************************************************/
834 Bitstring Bitstring::operator ^( const Bitstring &bitst)
837 Bitstring temp1(*this),temp2(bitst);
839 //make size bitst equal to *this
840 if (lengthBlock > bitst.lengthBlock)
841 temp2.Resize(length);
844 for (i = 0; i<lengthBlock ; i++ )
845 temp1[i] ^= temp2[i];
850 /***********************************************************************
851 * Member: operator ~ ()
852 * Purpose: Overloads the bitwise not operator. Does a bitwise not with
854 * Return: bitwised not -> ~(*this)
855 ***********************************************************************/
856 Bitstring Bitstring::operator ~()
859 Bitstring temp1(*this);
863 for (i = 0; i<lengthBlock ; i++ )
864 temp1[i] = ~temp1[i];
866 temp1.Resize(this->Length());
873 /***********************************************************************
874 * Member: operator << (ostream& outs, Bitstring &strout)
875 * Purpose: Overloads the stream output operator. Converts the bitstring to a
876 * C-string and returns it to "ostream".
877 * Return: outs -> converted bitstring
878 ***********************************************************************/
879 ostream& operator << (ostream& outs, const Bitstring &strout)
885 strout.BitstrToString(tmp);
889 for (int i = 0; i < strout.lengthBlock;i++) {
890 sprintf(tmp,"%08x",strout[i]);
893 // outs << hex << setw(8) << setfill('0') << strout[i];
898 /***********************************************************************
899 * Member: operator >> (istream& ins, Bitstring &instr)
900 * Purpose: Overloads the stream input operator. Converts the C-string to a
903 ***********************************************************************/
904 istream& operator >> (istream& ins, Bitstring &instr)
909 instr.StringToBitstr(str);