renamed: Conv::comma_digits to Conv::round

added:   bool Conv::base_round
         if 'base_round' is true and 'base' is different from 2, 4, 8, or 16
         and the result value is not an integer then we make an additional rounding
         (after converting the last digit from the result is skipped)
changed: in Big::ToString() some additional rounding (base_round) is now made only 
         when the value is not an integer


git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@244 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2009-11-24 05:14:54 +00:00
parent 0d1a57bdb4
commit bac79e0bfa
3 changed files with 40 additions and 19 deletions

View File

@ -1,4 +1,4 @@
Version 0.9.0 prerelease (2009.11.09):
Version 0.9.0 prerelease (2009.11.24):
* added: support for wide characters (wchar_t, std::wstring)
* added: Big::IsInteger()
returns true if the value is integer (without fraction)
@ -68,6 +68,8 @@
base 4: 1.3333333333333222
base 8: 1.77777777724
base 16: 1.FFFFFFEA
* changed: in Big::ToString() some additional rounding (base_round) is now made only
when the value is not an integer
* removed: Parser<>::SetFactorialMax() method
the factorial() is such a fast now that we don't need the method longer
* removed: ErrorCode::err_too_big_factorial

View File

@ -2871,7 +2871,7 @@ public:
uint base = 10,
bool scient = false,
sint scient_from = 15,
sint comma_digits = -1,
sint round = -1,
bool trim_zeroes = true,
wchar_t comma = '.' ) const
{
@ -2880,7 +2880,7 @@ public:
conv.base = base;
conv.scient = scient;
conv.scient_from = scient_from;
conv.comma_digits = comma_digits;
conv.round = round;
conv.trim_zeroes = trim_zeroes;
conv.comma = static_cast<uint>(comma);
@ -2896,7 +2896,7 @@ public:
uint base = 10,
bool scient = false,
sint scient_from = 15,
sint comma_digits = -1,
sint round = -1,
bool trim_zeroes = true,
wchar_t comma = '.' ) const
{
@ -2905,7 +2905,7 @@ public:
conv.base = base;
conv.scient = scient;
conv.scient_from = scient_from;
conv.comma_digits = comma_digits;
conv.round = round;
conv.trim_zeroes = trim_zeroes;
conv.comma = static_cast<uint>(comma);
@ -3017,7 +3017,7 @@ private:
we're rounding the mantissa only if the base is different from 2,4,8 or 16
(this formula means that the number of bits in the base is greater than one)
*/
if( conv.base!=2 && conv.base!=4 && conv.base!=8 && conv.base!=16 )
if( conv.base_round && conv.base!=2 && conv.base!=4 && conv.base!=8 && conv.base!=16 )
if( ToString_RoundMantissa<string_type, char_type>(result, conv, new_exp) )
{
Misc::AssignString(result, error_overflow_msg);
@ -3529,11 +3529,17 @@ private:
if( new_man.length() < 2 )
return 0;
// the rounding is only made when new_exp is less than zero
// if new_exp is greater or equal zero then the value is integer and
// don't have to be rounded
if( !new_exp.IsSign() )
return 0;
typename string_type::size_type i = new_man.length() - 1;
// we're erasing the last character
uint digit = Misc::CharToDigit( new_man[i] );
new_man.erase( i, 1 );
new_man.erase(i, 1);
uint carry = new_exp.AddOne();
// if the last character is greater or equal 'base/2'
@ -3813,7 +3819,7 @@ private:
void ToString_CorrectDigitsAfterComma( string_type & new_man,
const Conv & conv ) const
{
if( conv.comma_digits >= 0 )
if( conv.round >= 0 )
ToString_CorrectDigitsAfterComma_Round<string_type, char_type>(new_man, conv);
if( conv.trim_zeroes )
@ -3881,15 +3887,15 @@ private:
// if 'max_digit_after_comma' is greater than 'after_comma' (or equal)
// we don't have anything for cutting
if( static_cast<StrSize>(conv.comma_digits) >= after_comma )
if( static_cast<StrSize>(conv.round) >= after_comma )
return;
uint last_digit = Misc::CharToDigit( new_man[ index + conv.comma_digits + 1 ], conv.base );
uint last_digit = Misc::CharToDigit( new_man[ index + conv.round + 1 ], conv.base );
// we're cutting the rest of the string
new_man.erase(index + conv.comma_digits + 1, after_comma - conv.comma_digits);
new_man.erase(index + conv.round + 1, after_comma - conv.round);
if( conv.comma_digits == 0 )
if( conv.round == 0 )
{
// we're cutting the comma operator as well
// (it's not needed now because we've cut the whole rest after the comma)

View File

@ -321,6 +321,7 @@ namespace ttmath
/*!
this struct is used when converting to/from a string
/temporarily only in Big::ToString() and Big::FromString()/
*/
struct Conv
{
@ -348,6 +349,21 @@ namespace ttmath
sint scient_from;
/*!
if 'base_round' is true and 'base' is different from 2, 4, 8, or 16
and the result value is not an integer then we make an additional rounding
(after converting the last digit from the result is skipped)
default: true
e.g.
Conv c;
c.base_round = false;
Big<1, 1> a = "0.1"; // decimal input
std::cout << a.ToString(c) << std::endl; // the result is: 0.099999999
*/
bool base_round;
/*!
used only in Big::ToString()
tells how many digits after comma are possible
@ -356,11 +372,11 @@ namespace ttmath
set it to zero if you want integer value only
for example when the value is:
12.345678 and comma_digit is 4
12.345678 and 'round' is 4
then the result will be
12.3457 (the last digit was rounded)
*/
sint comma_digits;
sint round;
/*!
@ -404,9 +420,6 @@ namespace ttmath
uint group_exp; // not implemented yet
/*!
*/
bool group_multiple; // not implemented yet
Conv()
@ -415,13 +428,13 @@ namespace ttmath
base = 10;
scient = false;
scient_from = 15;
comma_digits = -1; // !! change to 'round' ?
base_round = true;
round = -1;
trim_zeroes = true;
comma = '.';
comma2 = ',';
group = 0;
group_exp = 0;
group_multiple = true;
}
};