[R-gregmisc-users] SF.net SVN: r-gregmisc: [1136] trunk/SASxport/src
Brought to you by:
warnes
From: <wa...@us...> - 2007-08-12 03:12:44
|
Revision: 1136 http://r-gregmisc.svn.sourceforge.net/r-gregmisc/?rev=1136&view=rev Author: warnes Date: 2007-08-11 20:12:21 -0700 (Sat, 11 Aug 2007) Log Message: ----------- 1st attempt at rewriting cnxptiee.[ch] Modified Paths: -------------- trunk/SASxport/src/cnxptiee.h trunk/SASxport/src/test_fields.c trunk/SASxport/src/writeSAS.h Added Paths: ----------- trunk/SASxport/src/B8.h trunk/SASxport/src/IEEEtoIBM.c trunk/SASxport/src/MASKS.h trunk/SASxport/src/main.c trunk/SASxport/src/reverse.c Added: trunk/SASxport/src/B8.h =================================================================== --- trunk/SASxport/src/B8.h (rev 0) +++ trunk/SASxport/src/B8.h 2007-08-12 03:12:21 UTC (rev 1136) @@ -0,0 +1,60 @@ +/* Binary constant generator macro +By Tom Torfs - donated to the public domain +*/ + +#include <sys/types.h> + + +/* All macro's evaluate to compile-time constants */ + +/* *** helper macros *** / + +/* turn a numeric literal into a hex constant +(avoids problems with leading zeroes) +8-bit constants max value 0x11111111, always fits in unsigned long +*/ +#define HEX__(n) 0x##n##LU + +/* 8-bit conversion function */ +#define B8__(x) ((x&0x0000000FLU)?1:0) \ ++((x&0x000000F0LU)?2:0) \ ++((x&0x00000F00LU)?4:0) \ ++((x&0x0000F000LU)?8:0) \ ++((x&0x000F0000LU)?16:0) \ ++((x&0x00F00000LU)?32:0) \ ++((x&0x0F000000LU)?64:0) \ ++((x&0xF0000000LU)?128:0) + +/* *** user macros *** / + +/* for upto 8-bit binary constants */ +#define B8(d) ((unsigned char)B8__(HEX__(d))) + +/* for upto 16-bit binary constants, MSB first */ +#define B16(dmsb,dlsb) (((unsigned short)B8(dmsb)<<8) \ ++ B8(dlsb)) + +/* for upto 32-bit binary constants, MSB first */ +#define B32(dmsb,db2,db3,dlsb) ( \ ++ ((unsigned long)B8(dmsb)<<24) \ ++ ((unsigned long)B8(db2)<<16) \ ++ ((unsigned long)B8(db3)<<8) \ ++ B8(dlsb)) + +/* for upto 32-bit binary constants, MSB first */ +#define B64(dmsb,db2,db3,db4,db5,db6,db7,dlsb) ( \ ++ ((unsigned int64_t)B8(dmsb<<56) \ ++ ((unsigned int64_t)B8(db2)<<48) \ ++ ((unsigned int64_t)B8(db3)<<40) \ ++ ((unsigned int64_t)B8(db4 <<32) \ ++ ((unsigned int64_t)B8(dm5)<<24) \ ++ ((unsigned int64_t)B8(db6)<<16) \ ++ ((unsigned int64_t)B8(db7)<<8 ) \ ++ B8(dlsb)) + + +/* Sample usage: +B8(01010101) = 85 +B16(10101010,01010101) = 43605 +B32(10000000,11111111,10101010,01010101) = 2164238933 +*/ Added: trunk/SASxport/src/IEEEtoIBM.c =================================================================== --- trunk/SASxport/src/IEEEtoIBM.c (rev 0) +++ trunk/SASxport/src/IEEEtoIBM.c 2007-08-12 03:12:21 UTC (rev 1136) @@ -0,0 +1,109 @@ +//#include "writeSAS.h" + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#import <assert.h> +#import <sys/types.h> + +typedef struct { /* IBM floating point format */ + unsigned sign : 1; /* Sign bit */ + unsigned exponent: 7; /* Exponent */ + //unsigned fraction: 56; /* Fraction */ + unsigned fraction1: 24; /* Top half of fraction */ + unsigned fraction2: 32; /* Lower half of fraction */ +} IBM_fp_struct; + + +typedef struct { /* IEEE floating point format */ + unsigned sign : 1; /* Sign bit */ + unsigned exponent: 11; /* Exponent */ + // unsigned fraction: 52; /* Fraction */ + unsigned fraction1: 20; /* Top half of fraction */ + unsigned fraction2: 32; /* Lower half of fraction */ +} IEEE_fp_struct; + + +int IEEEtoIBM(double *ieee, double *ibm ) +{ + IEEE_fp_struct *ieee_fp = (IEEE_fp_struct*) ieee; + IBM_fp_struct *ibm_fp = (IBM_fp_struct* ) ibm; + int64_t sign; + int64_t exponent; + int64_t fraction; + short low_exp_bits; + + /*** Extract Pieces ***/ + // Sign = Ieee & Ieee_Sign; + // Exponent = *Ieee & Ieee_Exp; + // Fraction = *Ieee & Ieee_Frac; + + printf("1\n"); + + /*** copy IEEE sign to IBM sign ***/ + ibm_fp->sign = ieee_fp->sign; + + printf("2\n"); + + /*** convert IEEE exponent to IBM exponent ***/ + exponent = ieee_fp->exponent; + + printf("3\n"); + + /* store lowest 2 bits from exponent */ + low_exp_bits = exponent % 16; + + + printf("4\n"); + + /* divide exponent by 4 to get from IEEE pow(2) exponent to IBM pow(16) exponent */ + exponent = exponent >> 2; + + printf("5\n"); + + + /* put it into the return value */ + ibm_fp->exponent = exponent; + + printf("6\n"); + + + /*** convert IEEE fraction to IBM fraction */ + fraction = ((int64_t) ieee_fp->fraction1 ) << 32 | ((int64_t) ieee_fp->fraction2); + + printf("7\n"); + + + /* shift left by low order bits lost from exponent */ + fraction = fraction << (low_exp_bits && 0x03); + + + printf("8\n"); + + /* add leading 1 bit */ + fraction >> 1; + fraction = fraction | ( ((int64_t) 1) <<55 ); + + printf("9\n"); + + + ibm_fp->fraction1 = (int32_t) (fraction >> 32) | 0x0FFFFF; + ibm_fp->fraction2 = (int32_t) fraction; + + + printf("10\n"); + + + char *buf= (char*) ibm; + char tmp; + int i; + for(i=0; i<8; i++) + { + tmp = buf[7-i]; + buf[7-i] = buf[i]; + buf[i] = tmp; + } + + return 0; +} + Added: trunk/SASxport/src/MASKS.h =================================================================== --- trunk/SASxport/src/MASKS.h (rev 0) +++ trunk/SASxport/src/MASKS.h 2007-08-12 03:12:21 UTC (rev 1136) @@ -0,0 +1,23 @@ +/* Masks for IBM fields */ +#define IBM_SIGN B64(10000000, 0000000, 0000000, 00000000, \ + 00000000, 0000000, 0000000, 00000000) + +#define IBM_EXP B64(01111111, 0000000, 0000000, 00000000, \ + 00000000, 0000000, 0000000, 00000000) + +#define IBM_FRAC B64(00000000, 1111111, 1111111, 11111111, \ + 11111111, 1111111, 1111111, 11111111) + +#define IBM_FRAC_MSB B64(00000000, 1000000, 0000000, 00000000, \ + 00000000, 0000000, 0000000, 00000000) + +/* Masks for IEEE fields */ +#define IEEE_SIGN B64(10000000, 0000000, 0000000, 00000000, \ + 00000000, 0000000, 0000000, 00000000) + +#define IEEE_EXP B64(01111111, 1111000, 0000000, 00000000, \ + 00000000, 0000000, 0000000, 00000000) + +#define IEEE_FRAC B64(00000000, 0000111, 1111111, 11111111, \ + 11111111, 1111111, 1111111, 11111111) + Modified: trunk/SASxport/src/cnxptiee.h =================================================================== --- trunk/SASxport/src/cnxptiee.h 2007-08-11 23:48:34 UTC (rev 1135) +++ trunk/SASxport/src/cnxptiee.h 2007-08-12 03:12:21 UTC (rev 1136) @@ -23,13 +23,13 @@ int get_native(); #endif -#ifdef BIG_ENDIAN -#define REVERSE(a,b) -#endif +/* #ifdef BIG_ENDIAN */ +/* #define REVERSE(a,b) */ +/* #endif */ -#ifdef LITTLE_ENDIAN -#define DEFINE_REVERSE -void REVERSE(); -#endif +/* #ifdef LITTLE_ENDIAN */ +/* #define DEFINE_REVERSE */ +/* void REVERSE(); */ +/* #endif */ #endif /* CNXPTIEE */ Added: trunk/SASxport/src/main.c =================================================================== --- trunk/SASxport/src/main.c (rev 0) +++ trunk/SASxport/src/main.c 2007-08-12 03:12:21 UTC (rev 1136) @@ -0,0 +1,55 @@ +#include <math.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#import <assert.h> +#import <sys/types.h> + + +extern int cnxptiee(char *from, int fromtype, char *to, int totype); +int IEEEtoIBM(double *ieee, double *ibm ); + +int main(int argc, char *argv) +{ + double ieee; + double ibm_sas, ieee_sas; + double ibm_our, ieee_our; + char *ibm_sas_c = (char*) &ibm_sas; + char *ibm_our_c = (char*) &ibm_our; + + + for(int i=0; i<10; i++) + { + ieee = pow(2.0, ((double) i)) + 1.0 + 1.0 / ( ((double) i) + 1.0); + + /* from ieee to ibm, SAS code */ + cnxptiee( (char*) &ieee, 0, (char*) &ibm_sas, 1 ); + + /* and back again, SAS code */ + cnxptiee( (char*) &ibm_sas, 1, (char*) &ieee_sas, 0 ); + + + /* from ieee to ibm, our code */ + IEEEtoIBM( &ieee, &ibm_our ); + + /* and back again, SAS code */ + cnxptiee( (char*) &ibm_our, 1, (char*) &ieee_our, 0 ); + + + printf("i=%5d, ieee=%10f, ieee_sas=%10f ieee_our=%10f \n", i, + ieee, ieee_sas, ieee_our); + + for(int index=0; index<8; index++) + { + printf(" "); + printf("%2x ", ibm_sas_c[index]); + printf("%2x ", ibm_our_c[index]); + printf("\n"); + } + printf("\n"); + + } + + return 0; +} + Added: trunk/SASxport/src/reverse.c =================================================================== --- trunk/SASxport/src/reverse.c (rev 0) +++ trunk/SASxport/src/reverse.c 2007-08-12 03:12:21 UTC (rev 1136) @@ -0,0 +1,83 @@ +#include "writeSAS.h" + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#import <assert.h> +#import <sys/types.h> + +/* reverse: convert current byte order to little endian */ +void reverse( u_char *intp, size_t size) +{ + static u_char endianTest[2] = {0x01,0x00}; + size_t i; + u_char tmp; + +#if !defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN) + /* Test if we are on a big endian or little endian platform */ + if( (short) *endianTest == 1 ) + { + /* Little Endian */ + /* Do nothing */ + return; + } +#endif + + /* Big Endian */ + /* Swap bytes */ + for(i=0; i < size/2; i++) + { + tmp = (u_char) intp[i]; + intp[i] = intp[size-i-1]; + intp[size-i] = tmp; + } + + return; +} + + +/* test code */ +void test_reverse() +{ + u_char byte_pattern[1] = { 0x00 }; + u_char byte_value = 0x00; + + u_char short_pattern[2] = { 0x00, 0x01 }; /* NB: little endian byte pattern */ + short short_value = 0x0100; /* NB: hex is written big endian */ + + u_char int_pattern[4] = { 0x0, 0x01, 0x02, 0x03 }; + int int_value = 0x03020100; + + u_char long_pattern[4] = { 0x0, 0x01, 0x02, 0x03 }; + long long_value = 0x03020100; + + /* Do the reverse, then test */ + + /* byte */ + REVERSE( &byte_value, sizeof(u_char) ); + assert( (u_char) *byte_pattern == byte_value ); + + /* short */ + REVERSE( &short_value, sizeof(short) ); + assert( *((short *) short_pattern) == short_value ); + + /* int */ + REVERSE( &int_value, sizeof(int) ); + assert( *((int *) int_pattern) == int_value ); + + /* long */ + REVERSE( &long_value, sizeof(long) ); + assert( *((long*) long_pattern) == long_value ); + +} + + +#ifdef DO_TEST +int main(int argc, u_char *argv) +{ + test_reverse(); +} + + + +#endif Modified: trunk/SASxport/src/test_fields.c =================================================================== --- trunk/SASxport/src/test_fields.c 2007-08-11 23:48:34 UTC (rev 1135) +++ trunk/SASxport/src/test_fields.c 2007-08-12 03:12:21 UTC (rev 1136) @@ -151,6 +151,8 @@ return 0; } + + void doTest() { /* small buffer */ @@ -167,5 +169,9 @@ test_blankCopy(BIG); test_zeroCopy(BIG); + + + /* test reverse */ + test_reverse(); } Modified: trunk/SASxport/src/writeSAS.h =================================================================== --- trunk/SASxport/src/writeSAS.h 2007-08-11 23:48:34 UTC (rev 1135) +++ trunk/SASxport/src/writeSAS.h 2007-08-12 03:12:21 UTC (rev 1136) @@ -27,7 +27,9 @@ #include <R.h> #include <Rinternals.h> +#include <sys/types.h> + /***** * Useful constants *****/ @@ -35,6 +37,19 @@ #define MISSING 0x2e000000 /* Standard SAS missing value: '.' */ /***** + REVERSE macro, used as a wrapper for the reverse() function to avoid + compiling/calling it on little-endian. + *****/ + +#ifdef BIG_ENDIAN +# define REVERSE(a,b) reverse( (u_char*) a, (size_t) b) +#elif defined(LITTLE_ENDIAN) +# define REVERSE(a,b) +#else +# define REVERSE(a,b) reverse( (u_char*) a, (size_t) b) +#endif + +/***** * Useful macro functions *****/ @@ -152,4 +167,7 @@ void doTest(); +void reverse( u_char *intp, size_t size); + + #endif /* FIELDS_H */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |