// Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Multiprecision decimal numbers. // For floating-point formatting only; not general purpose. // Only operations are assign and (binary) left/right shift. // Can do binary floating point in multiprecision decimal precisely // because 2 divides 10; cannot do decimal floating point // in multiprecision binary precisely. package decimal type floatInfo struct { mantbits uint expbits uint bias int } var float32info = floatInfo{23, 8, -127} var float64info = floatInfo{52, 11, -1023} // roundShortest rounds d (= mant * 2^exp) to the shortest number of digits // that will let the original floating point value be precisely reconstructed. func roundShortest(d *decimal, mant uint64, exp int, flt *floatInfo) { // If mantissa is zero, the number is zero; stop now. if mant == 0 { d.nd = 0 return } // Compute upper and lower such that any decimal number // between upper and lower (possibly inclusive) // will round to the original floating point number. // We may see at once that the number is already shortest. // // Suppose d is not denormal, so that 2^exp <= d < 10^dp. // The closest shorter number is at least 10^(dp-nd) away. // The lower/upper bounds computed below are at distance // at most 2^(exp-mantbits). // // So the number is already shortest if 10^(dp-nd) > 2^(exp-mantbits), // or equivalently log2(10)*(dp-nd) > exp-mantbits. // It is true if 332/100*(dp-nd) >= exp-mantbits (log2(10) > 3.32). minexp := flt.bias + 1 // minimum possible exponent if exp > minexp && 332*(d.dp-d.nd) >= 100*(exp-int(flt.mantbits)) { // The number is already shortest. return } // d = mant << (exp - mantbits) // Next highest floating point number is mant+1 << exp-mantbits. // Our upper bound is halfway between, mant*2+1 << exp-mantbits-1. upper := new(decimal) upper.Assign(mant*2 + 1) upper.Shift(exp - int(flt.mantbits) - 1) // d = mant << (exp - mantbits) // Next lowest floating point number is mant-1 << exp-mantbits, // unless mant-1 drops the significant bit and exp is not the minimum exp, // in which case the next lowest is mant*2-1 << exp-mantbits-1. // Either way, call it mantlo << explo-mantbits. // Our lower bound is halfway between, mantlo*2+1 << explo-mantbits-1. var mantlo uint64 var explo int if mant > 1<