diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 9f96c7b190..59ce079e40 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,23 @@ +19990519-23:50 EST David G. Holm + * source/rtl/extend.c + - Use wDec = hb_set.HB_SET_DECIMALS instead of wDec = 2. + - _retnd() and _stornd() now set wLength to 20 if the value is over 10 digits. + * source/rtl/itemapi.c + - Use wDec = hb_set.HB_SET_DECIMALS instead of wDec = 2. + - hb_itemPutND() now sets wLength to 20 if the value is over 10 digits. + * source/rtl/math.c + - Restored HARBOUR INT() back to use _retnl( _parnd( 1 ) ), because the + problem was not in the Borland C++ 3.1 compiler, but in the hb_outstd() + case for IT_LONG in console.c (see 19990518-17:30 EDT David G. Holm for + the incorrect correction and 19990519-21:40 EST David G. Holm for the + fix to hb_outstd() in console.c). + * source/vm/hvm.c + - Div(), Modulus(), and Power() set wDec to hb_set.HB_SET_DECIMALS. + - Dec(), Inc(), FOR, and Negate() leave wDec unchanged. + - Plus() and Minus() set wDec to the larger of the two parameter wDec values. + - Mult() sets wDec to the sum of the two parameter wDec values. + - PushDouble() now sets wLength to 20 if the value is over 10 digits. + 19990519-22:00 EST David G. Holm * source/rtl/environ.c - Do Windows version check even when #if defined(_Windows). diff --git a/harbour/source/rtl/extend.c b/harbour/source/rtl/extend.c index 077490f7ed..665520f5f8 100644 --- a/harbour/source/rtl/extend.c +++ b/harbour/source/rtl/extend.c @@ -3,6 +3,7 @@ */ #include +#include #include #include @@ -351,8 +352,9 @@ void _retnd( double dNumber ) { ItemRelease( &stack.Return ); stack.Return.wType = IT_DOUBLE; - stack.Return.wLength = 10; - stack.Return.wDec = 2; + if( dNumber > 10000000000.0 ) stack.Return.wLength = 20; + else stack.Return.wLength = 10; + stack.Return.wDec = hb_set.HB_SET_DECIMALS; stack.Return.value.dNumber = dNumber; } @@ -598,8 +600,9 @@ void _stornd( double dValue, WORD wParam, ... ) pItemRef = stack.pItems + pItem->value.wItem; ItemRelease( pItemRef ); pItemRef->wType = IT_DOUBLE; - pItemRef->wLength = 10; - pItemRef->wDec = 2; + if( dValue > 10000000000.0 ) pItemRef->wLength = 20; + else pItemRef->wLength = 10; + pItemRef->wDec = hb_set.HB_SET_DECIMALS; pItemRef->value.dNumber = dValue; } } diff --git a/harbour/source/rtl/itemapi.c b/harbour/source/rtl/itemapi.c index 9fb7ec998f..7aff4af881 100644 --- a/harbour/source/rtl/itemapi.c +++ b/harbour/source/rtl/itemapi.c @@ -5,6 +5,7 @@ #include #include #include +#include /* TODO: Remove these when the extend system has been modified */ #define hb_xgrab _xgrab @@ -349,8 +350,9 @@ PITEM hb_itemPutND( PITEM pItem, double dNumber ) pItem = hb_itemNew(0); pItem->wType = IT_DOUBLE; - pItem->wLength = 10; - pItem->wDec = 2; + if( dNumber > 10000000000.0 ) pItem->wLength = 20; + else pItem->wLength = 10; + pItem->wDec = hb_set.HB_SET_DECIMALS; pItem->value.dNumber = dNumber; return pItem; } @@ -364,7 +366,7 @@ PITEM hb_itemPutNL( PITEM pItem, long lNumber ) pItem->wType = IT_DOUBLE; pItem->wLength = 10; - pItem->wDec = 2; + pItem->wDec = hb_set.HB_SET_DECIMALS; pItem->value.lNumber = lNumber; return pItem; } diff --git a/harbour/source/rtl/math.c b/harbour/source/rtl/math.c index a9fb9fcee9..37cd20e491 100644 --- a/harbour/source/rtl/math.c +++ b/harbour/source/rtl/math.c @@ -85,26 +85,8 @@ HARBOUR INT( void ) { if( _pcount() == 1 ) { - PITEM pNumber = _param(1, IT_NUMERIC); - double dTemp; - - if( pNumber ) switch( pNumber->wType ) - { - case IT_INTEGER: - _retni( pNumber->value.iNumber ); - break; - - case IT_LONG: - _retnl( pNumber->value.lNumber ); - break; - - case IT_DOUBLE: - modf( pNumber->value.dNumber, &dTemp ); - _retnd( dTemp ); /* Return integer part of double value */ - stack.Return.wLength = 10; /* Set return length same as int or long */ - stack.Return.wDec = 0; /* Set zero decimal places */ - /* Because _retnl( _parnd( 1 ) ); doesn't work in Borland Turbo C++ 3.1 */ - } + if( _param(1, IT_NUMERIC) ) + _retnl( _parnd( 1 ) ); else { PITEM pError = _errNew(); diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 1a0b518f74..be28dc4f1b 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -75,13 +75,13 @@ void Power( void ); /* power the latest two values on the stack, remo void Push( PITEM pItem ); /* pushes a generic item onto the stack */ void PushBlock( BYTE * pCode, WORD wSize, WORD wParam, PSYMBOL pSymbols ); /* creates a codeblock */ void PushDate( LONG lDate ); /* pushes a long date onto the stack */ -void PushDouble( double lNumber ); /* pushes a double number onto the stack */ +void PushDouble( double lNumber, WORD wDec ); /* pushes a double number onto the stack */ void PushLocal( SHORT iLocal ); /* pushes the containts of a local onto the stack */ void PushLocalByRef( SHORT iLocal ); /* pushes a local by refrence onto the stack */ void PushLogical( int iTrueFalse ); /* pushes a logical value onto the stack */ void PushLong( long lNumber ); /* pushes a long number onto the stack */ void PushNil( void ); /* in this case it places nil at self */ -void PushNumber( double dNumber ); /* pushes a number on to the stack and decides if it is integer, long or double */ +void PushNumber( double dNumber, WORD wDec ); /* pushes a number on to the stack and decides if it is integer, long or double */ void PushStatic( WORD wStatic ); /* pushes the containts of a static onto the stack */ void PushString( char * szText, WORD wLength ); /* pushes a string on to the stack */ void PushSymbol( PSYMBOL pSym ); /* pushes a function pointer onto the stack */ @@ -469,7 +469,7 @@ void VirtualMachine( PBYTE pCode, PSYMBOL pSymbols ) break; case _PUSHDOUBLE: - PushDouble( * ( double * ) ( &pCode[ w + 1 ] ) ); + PushDouble( * ( double * ) ( &pCode[ w + 1 ] ), hb_set.HB_SET_DECIMALS ); w += 1 + sizeof( double ); break; @@ -629,7 +629,7 @@ void Dec( void ) if( IS_NUMERIC( stack.pPos - 1 ) ) { dNumber = PopDouble(); - PushNumber( --dNumber ); + PushNumber( --dNumber, stack.pPos->wDec ); } else if( IS_DATE( stack.pPos - 1 ) ) { @@ -644,7 +644,7 @@ void Div( void ) double d2 = PopDouble(); double d1 = PopDouble(); - PushNumber( d1 / d2 ); + PushNumber( d1 / d2, hb_set.HB_SET_DECIMALS ); } void Do( WORD wParams ) @@ -843,7 +843,7 @@ void ForTest( void ) /* Test to check the end point of the FOR */ printf( "step of zero will cause endless loop" ); /* Add some break code or so... */ iEqual = PopLogical(); /* Logical should be on top of stack */ - PushNumber( dStep ); /* Push the step expression back on the stack */ + PushNumber( dStep, stack.pPos->wDec ); /* Push the step expression back on the stack */ PushLogical( iEqual ); } else @@ -997,7 +997,7 @@ void Inc( void ) if( IS_NUMERIC( stack.pPos - 1 ) ) { dNumber = PopDouble(); - PushNumber( ++dNumber ); + PushNumber( ++dNumber, stack.pPos->wDec ); } else if( IS_DATE( stack.pPos - 1 ) ) { @@ -1242,15 +1242,18 @@ void Minus( void ) if( IS_NUMERIC( stack.pPos - 1 ) && IS_NUMERIC( stack.pPos - 2 ) ) { + WORD wDec2, wDec1; dNumber2 = PopNumber(); + wDec2 = stack.pPos->wDec; dNumber1 = PopNumber(); - PushNumber( dNumber1 - dNumber2 ); + wDec1 = stack.pPos->wDec; + PushNumber( dNumber1 - dNumber2, (wDec1 > wDec2) ? wDec1 : wDec2 ); } else if( IS_DATE( stack.pPos - 1 ) && IS_DATE( stack.pPos - 2 ) ) { lDate2 = PopDate(); lDate1 = PopDate(); - PushNumber( lDate1 - lDate2 ); + PushNumber( lDate1 - lDate2, hb_set.HB_SET_DECIMALS ); } else if( IS_NUMERIC( stack.pPos - 1 ) && IS_DATE( stack.pPos - 2 ) ) { @@ -1267,15 +1270,18 @@ void Modulus( void ) double d2 = PopDouble(); double d1 = PopDouble(); - PushNumber( ( long ) d1 % ( long ) d2 ); + PushNumber( ( long ) d1 % ( long ) d2, hb_set.HB_SET_DECIMALS ); } void Mult( void ) { - double d2 = PopDouble(); - double d1 = PopDouble(); + WORD wDec2, wDec1; + double d1, d2 = PopDouble(); + wDec2 = stack.pPos->wDec; + d1 = PopDouble(); + wDec1 = stack.pPos->wDec; - PushNumber( d1 * d2 ); + PushNumber( d1 * d2, wDec1 + wDec2 ); } void OperatorCall( PITEM pItem1, PITEM pItem2, char *szSymbol ) @@ -1334,9 +1340,13 @@ void Plus( void ) else if( IS_NUMERIC( pItem1 ) && IS_NUMERIC( pItem2 ) ) { + WORD wDec2, wDec1; dNumber2 = PopDouble(); + wDec2 = stack.pPos->wDec; dNumber1 = PopDouble(); - PushNumber( dNumber1 + dNumber2 ); + wDec1 = stack.pPos->wDec; + + PushNumber( dNumber1 + dNumber2, (wDec1 > wDec2) ? wDec1 : wDec2 ); } else if( IS_DATE( pItem1 ) && IS_DATE( pItem2 ) ) @@ -1513,7 +1523,7 @@ void Power( void ) double d2 = PopDouble(); double d1 = PopDouble(); - PushNumber( pow( d1, d2 ) ); + PushNumber( pow( d1, d2 ), hb_set.HB_SET_DECIMALS ); } void PushLogical( int iTrueFalse ) @@ -1560,14 +1570,13 @@ void PushNil( void ) HBDEBUG( "PushNil\n" ); } -void PushNumber( double dNumber ) +void PushNumber( double dNumber, WORD wDec ) { if( ! dNumber ) PushInteger( 0 ); - /* QUESTION: Is this a valid way to check for decimals ? */ - else if( ( long ) dNumber < dNumber ) /* it contains decimals */ - PushDouble( dNumber ); + else if( wDec ) + PushDouble( dNumber, wDec ); else if( SHRT_MIN <= dNumber && dNumber <= SHRT_MAX ) PushInteger( dNumber ); @@ -1576,7 +1585,7 @@ void PushNumber( double dNumber ) PushLong( dNumber ); else - PushDouble( dNumber ); + PushDouble( dNumber, hb_set.HB_SET_DECIMALS ); } void PushStatic( WORD wStatic ) @@ -1644,13 +1653,14 @@ void PushDate( LONG lDate ) HBDEBUG( "PushDate\n" ); } -void PushDouble( double dNumber ) +void PushDouble( double dNumber, WORD wDec ) { ItemRelease( stack.pPos ); stack.pPos->wType = IT_DOUBLE; stack.pPos->value.dNumber = dNumber; - stack.pPos->wLength = 10; - stack.pPos->wDec = 2; + if( dNumber >= 10000000000.0 ) stack.pPos->wLength = 20; + else stack.pPos->wLength = 10; + stack.pPos->wDec = wDec; StackPush(); HBDEBUG( "PushDouble\n" ); }