This is for exploring and demonstrating ways to extend the available integer math in C. Cコンパイラが提供する整数を拡張するための探険用のソースコードです。
Rev. | 056c8c9d381867aa3d96bcf05e9a165e42771547 |
---|---|
大小 | 4,666 字节 |
时间 | 2013-07-29 11:34:41 |
作者 | Joel Matthew Rees |
Log Message | Where I ran out of time last week. Demonstrats add/sub/mul/bitdiv.
|
/* Subtraction tester for an eight-bit framework
// for testing various arithmetic techniques.
// Written by Joel Matthew Rees
// Copyright 2013, Joel Matthew Rees
// Distribution and use permitted under terms of the GPL v. 3,
// See the included file, LICENSE.TXT,
// or on-line at <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include "nibBit.h"
int main( int argc, char * argv[] )
{ unsigned long i, j;
long badB = 0;
long badS = 0;
long rangeMissB = 0;
long rangeMissS = 0;
long dividendlimit = 0xffff;
long dividendstart = 0;
long divisorlimit = 0xff;
long divisorstart = 1;
unsigned long countChecked = 0;
if ( argc > 3 )
{ char * scan;
int i;
for ( i = 1; i < argc; ++i )
{ switch ( argv[ i ][ 0 ] )
{
case 'N': dividendlimit = strtoul( argv[ i ] + 1, &scan, 0 );
break;
case 'n': dividendstart = strtoul( argv[ i ] + 1, &scan, 0 );
break;
case 'D': divisorlimit = strtoul( argv[ i ] + 1, &scan, 0 );
break;
case 'd': divisorstart = strtoul( argv[ i ] + 1, &scan, 0 );
break;
}
if ( divisorstart < 1 )
{ divisorstart = 1;
}
}
/*
printf( "dividend start, limit: %lx, %lx -- divisor start, limit: %lx %lx\n",
dividendstart, dividendlimit, divisorstart, divisorlimit );
return -1;
*/
}
else if ( argc > 2 )
{ char * scan;
dividendstart = strtoul( argv[ 1 ], &scan, 0 );
dividendlimit = strtoul( argv[ 2 ], &scan, 0 );
}
else if ( argc > 1 )
{ char * scan;
dividendlimit = strtoul( argv[ 1 ], &scan, 0 );
}
initMyStack();
for ( i = dividendstart; i <= dividendlimit; ++i )
{ /* no divide by zero */
for ( j = divisorstart; j <= divisorlimit; ++j )
{ unsigned q = i / j;
unsigned r = i % j;
unsigned sq, sr, bq, br;
++countChecked;
( * --mySP ) = (uchar_t) i;
( * --mySP ) = (uchar_t) ( i >> CHAR_BIT );
( * --mySP ) = (uchar_t) j;
nibBUDiv();
bq = ( * mySP++ );
br = ( * mySP++ );
( * --mySP ) = (uchar_t) i;
( * --mySP ) = (uchar_t) ( i >> CHAR_BIT );
( * --mySP ) = (uchar_t) j;
nibUDiv();
#if defined TESTUDIVHIGHWORD
sq = ( * mySP++ ) << BYTEBITS;
sq |= ( * mySP++ );
#else /* !defined TESTUDIVHIGHWORD */
sq = ( * mySP++ );
#endif /* defined TESTUDIVHIGHWORD */
sr = ( * mySP++ );
if ( ( q != sq ) || ( r != sr ) )
{ if ( q > 0xff )
{ rangeMissS += 1;
printf( "out-of-range synthetic (%ld): \n", rangeMissS );
printf( "%ld / %ld = %d r %d => bin: %d r %d | synth: %d r %d\n",
i, j, q, r, bq, br, sq, sr );
printf( "0x%05lx / 0x%03lx = 0x%05x r 0x%03x => bin: 0x%05x r 0x%03x | synth: : 0x%05x r 0x%03x\n",
i, j, q, r, bq, br, sq, sr );
}
else
{
badS += 1;
printf( "*** bad synthetic (%ld): \n", badS );
printf( "%ld / %ld = %d r %d => bin: %d r %d | synth: %d r %d\n",
i, j, q, r, bq, br, sq, sr );
printf( "0x%05lx / 0x%03lx = 0x%05x r 0x%03x => bin: 0x%05x r 0x%03x | synth: : 0x%05x r 0x%03x\n",
i, j, q, r, bq, br, sq, sr );
}
}
else if ( ( q != bq ) || ( r != br ) )
{ if ( q > 0xff )
{ rangeMissB += 1;
/*
printf( "out-of-range binary shift (%ld): \n", rangeMissB );
printf( "%ld / %ld = %d r %d => bin: %d r %d | synth: %d r %d\n",
i, j, q, r, bq, br, sq, sr );
printf( "0x%05lx / 0x%03lx = 0x%05x r 0x%03x => bin: 0x%05x r 0x%03x | synth: : 0x%05x r 0x%03x\n",
i, j, q, r, bq, br, sq, sr );
*/
}
else
{
badB += 1;
printf( "*** bad binary shift (%ld): ", badB );
printf( "%ld / %ld = %d r %d => bin: %d r %d | synth: %d r %d\n",
i, j, q, r, bq, br, sq, sr );
printf( "0x%05lx / 0x%03lx = 0x%05x r 0x%03x => bin: 0x%05x r 0x%03x | synth: : 0x%05x r 0x%03x\n",
i, j, q, r, bq, br, sq, sr );
}
}
}
printf( "i: %04lx -- Range miss bin: %ld, synth: %ld out of %ld\n",
i, rangeMissB, rangeMissS, countChecked );
printf( "Bad counts -- binary: %ld, synthetic: %ld\n", badB, badS );
}
return badB | badS;
}