[R-gregmisc-users] SF.net SVN: r-gregmisc:[1841] trunk/SASxport/src/ieee2ibm.c
Brought to you by:
warnes
From: <wa...@us...> - 2014-07-18 18:38:00
|
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. |