Revision: 1841
http://sourceforge.net/p/r-gregmisc/code/1841
Author: warnes
Date: 2014-07-18 18:37:51 +0000 (Fri, 18 Jul 2014)
Log Message:
-----------
Make sure all left shifts are explicitly typed as unsigned in to avoid
undefined behavior.
Modified Paths:
--------------
trunk/SASxport/src/ieee2ibm.c
Modified: trunk/SASxport/src/ieee2ibm.c
===================================================================
--- trunk/SASxport/src/ieee2ibm.c 2014-07-18 17:11:52 UTC (rev 1840)
+++ trunk/SASxport/src/ieee2ibm.c 2014-07-18 18:37:51 UTC (rev 1841)
@@ -45,95 +45,111 @@
static char numeric_NA[8] = {0x2e,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
- /*
- * IBM Format.
- * 7-bit exponent, base 16.
- * No hidden bits in mantissa (56 bits).
- */
- register int i;
- for( i=count-1; i >= 0; i-- ) {
- register unsigned int left, right;
- register int fix, exp, signbit;
+ /*
+ * IBM Format.
+ * 7-bit exponent, base 16.
+ * No hidden bits in mantissa (56 bits).
+ */
+ register int i;
+ for( i=count-1; i >= 0; i-- )
+ {
+ register unsigned int left, right;
+ register int fix, exp, signbit;
- left = (in[0]<<24) | (in[1]<<16) | (in[2]<<8) | in[3];
- right = (in[4]<<24) | (in[5]<<16) | (in[6]<<8) | in[7];
- in += 8;
+ left = ( (unsigned int) in[0]<<24) |
+ ( (unsigned int) in[1]<<16) |
+ ( (unsigned int) in[2]<<8 ) |
+ in[3];
+ right = ( (unsigned int) in[4]<<24) |
+ ( (unsigned int) in[5]<<16) |
+ ( (unsigned int) in[6]<<8 ) |
+ in[7];
+ in += 8;
- exp = ((left >> 20) & 0x7FF);
- signbit = (left & 0x80000000) >> 24;
+ exp = ((left >> 20) & 0x7FF);
+ signbit = (left & 0x80000000) >> 24;
- if( exp == 0 || exp == 0x7FF ) {
- *out++ = 0; /* IBM zero. No NAN */
- *out++ = 0;
- *out++ = 0;
- *out++ = 0;
- *out++ = 0;
- *out++ = 0;
- *out++ = 0;
- *out++ = 0;
- continue;
- }
+ if( exp == 0 || exp == 0x7FF )
+ {
+ *out++ = 0; /* IBM zero. No NAN */
+ *out++ = 0;
+ *out++ = 0;
+ *out++ = 0;
+ *out++ = 0;
+ *out++ = 0;
+ *out++ = 0;
+ *out++ = 0;
+ continue;
+ }
- left = (left & 0x000FFFFF) | 0x00100000;/* replace "hidden" bit */
+ left = (left & 0x000FFFFF) | 0x00100000;/* replace "hidden" bit */
- exp += 129 - 1023 -1; /* fudge, to make /4 and %4 work */
- fix = exp % 4; /* 2^4 == 16^1; get fractional exp */
- exp /= 4; /* excess 32, base 16 */
- exp += (64-32+1); /* excess 64, base 16, plus fudge */
- if( (exp & ~0xFF) != 0 ) {
- warning("IBM exponent overflow, generating NA\n");
- memcpy(out, numeric_NA, 8);
- out+= 8;
- continue;
- }
+ exp += 129 - 1023 -1; /* fudge, to make /4 and %4 work */
+ fix = exp % 4; /* 2^4 == 16^1; get fractional exp */
+ exp /= 4; /* excess 32, base 16 */
+ exp += (64-32+1); /* excess 64, base 16, plus fudge */
+ if( (exp & ~0xFF) != 0 )
+ {
+ warning("IBM exponent overflow, generating NA\n");
+ memcpy(out, numeric_NA, 8);
+ out+= 8;
+ continue;
+ }
- if( fix ) {
- left = (left<<fix) | (right >> (32-fix));
- right <<= fix;
- }
+ if( fix )
+ {
+ left = ( (unsigned int) left<<fix) | (right >> (32-fix));
+ right <<= fix;
+ }
- /* if( 0 && signbit ) { */
- if( 0 ) {
- /* The IBM actually uses complimented mantissa
- * and exponent.
- */
- left ^= 0xFFFFFFFF;
- right ^= 0xFFFFFFFF;
- if( right & 0x80000000 ) {
- /* There may be a carry */
- right += 1;
- if( (right & 0x80000000) == 0 ) {
- /* There WAS a carry */
- left += 1;
- }
- } else {
- /* There will be no carry to worry about */
- right += 1;
- }
- left &= 0x00FFFFFF;
- exp = (~exp) & 0x7F;
+ /* if( 0 && signbit ) { */
+ if( 0 )
+ {
+ /* The IBM actually uses complimented mantissa
+ * and exponent.
+ */
+ left ^= 0xFFFFFFFF;
+ right ^= 0xFFFFFFFF;
+ if( right & 0x80000000 )
+ {
+ /* There may be a carry */
+ right += 1;
+ if( (right & 0x80000000) == 0 )
+ {
+ /* There WAS a carry */
+ left += 1;
}
+ }
+ else
+ {
+ /* There will be no carry to worry about */
+ right += 1;
+ }
+ left &= 0x00FFFFFF;
+ exp = (~exp) & 0x7F;
+ }
- /* Not actually required, but for comparison purposes,
- * normalize the number. Remove for production speed.
- */
- while( (left & 0x00F00000) == 0 && left != 0 ) {
- if( signbit && exp <= 0x41 ) break;
+ /* Not actually required, but for comparison purposes,
+ * normalize the number. Remove for production speed.
+ */
+ while( (left & 0x00F00000) == 0 && left != 0 )
+ {
+ if( signbit && exp <= 0x41 ) break;
- left = (left << 4) | (right >> (32-4));
- right <<= 4;
- if(signbit) exp--;
- else exp++;
- }
+ left = ( (unsigned int) left << 4) | (right >> (32-4));
+ right <<= 4;
+ if(signbit) exp--;
+ else exp++;
+ }
- *out++ = signbit | exp;
- *out++ = left>>16;
- *out++ = left>>8;
- *out++ = left;
- *out++ = right>>24;
- *out++ = right>>16;
- *out++ = right>>8;
- *out++ = right;
- }
- return;
+ *out++ = signbit | exp;
+ *out++ = left>>16;
+ *out++ = left>>8;
+ *out++ = left;
+ *out++ = right>>24;
+ *out++ = right>>16;
+ *out++ = right>>8;
+ *out++ = right;
+ }
+ return;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|