bfloat precision question



Adam Majewski wrote:
> Hi,
>
> Can I estimate :
> fpprec>log2(x)
>
> ?fprec>log10(x)
>
> Adam
>
>
>
> Richard Fateman pisze:
>   
>> Figuring out stuff like this often requires that you look at the numbers 
>> in the radix representation in which the calculations
>> are done.
>> fpprec is a number which is converted to an (over) estimate of the 
>> number of BINARY bits required in the fraction part of a bfloat.
>> thus  fpprec:32   (decimal places)   is really 109  bits.    (try 
>> this:   fpprec:32;    ?fpprec;)
>>
>> the maxima variable $fpprec is what is set to 32.   the lisp variable 
>> fpprec is set to 109.
>>
>> The rounding for bfloats is done according to the round-to-nearest rule 
>> for IEEE floats. Maybe that is the answer you want.
>>
>> This rounding probably doubles or even quadruples the time taken for the 
>> basic arithmetic operation.
>>
>> RJF
>>
>>
>>  Sheldon Newhouse wrote:
>>
>> Hello,
>>     
>>>  I was looking at some of W. Kahan's papers on round-off errors and 
>>> found the following test for estimation of the roundoff error in a computer.
>>>
>>> In some notes on his web page entitled
>>>  "OLD Notes on Errors and Equation-Solving"
>>>
>>> he states the following
>>>
>>> If y fop z denotes the floating point representation of the mathematical 
>>> operation  y op z where
>>>     op is one of +,-,*,/, then
>>>
>>> y fop z = (y op z)/(1-a) 
>>>
>>> where
>>>
>>> abs(a) < abs( ( ((4.0/3.0 rounded) - 1.0)*3.0 - 1.0 )
>>>
>>>  There is a difference between the stated estimate for standard double 
>>> precision and the output using 'bfloat'. 
>>>  Kahan mentions that his estimate is an over-estimataion, so there is no 
>>> contradiction. 
>>>
>>> My question is whether the computed outcome with 'bfloat' is also a 
>>> correct upper estimate for 'a'.  Note: I did not check the mathematics 
>>> involved. I thought someone (maybe RJF) would know the answer immediately.
>>>
>>> Here are some outputs (maxima 5.18.1 with cmucl).
>>>
>>> (%i5) fpprec;
>>> (%o5)                                 16
>>> (%i6) abs(((4.0/3.0) - 1.0)*3.0 -1.0);
>>> (%o6)                        2.220446049250313e-16
>>>
>>> Here is the computation using 'bfloats'.
>>> (%i7) abs(((bfloat(4.0)/bfloat(3.0)) - bfloat(1.0))*bfloat(3.0) 
>>> -bfloat(1.0));
>>> (%o7)                        2.775557561562891b-17
>>>
>>> Is this smaller number an accurate estimate ?
>>>
>>> More generally,   does the method produce valid estimations for any 
>>> precision? 
>>>
>>> In particular,  are the following upper bounds valid?
>>>
>>> %i10) fpprec: 32;
>>> (%o10)                                32
>>> (%i11) abs(((bfloat(4.0)/bfloat(3.0)) - bfloat(1.0))*bfloat(3.0) 
>>> -bfloat(1.0));
>>> (%o11)               3.0814879110195773648895647081359b-33
>>> (%i12) fpprec: 64;
>>> (%o12)                                64
>>> (%i13) abs(((bfloat(4.0)/bfloat(3.0)) - bfloat(1.0))*bfloat(3.0) 
>>> -bfloat(1.0));
>>> (%o13) 3.798227098303919498989296907824782861688386333447977986511911996b-65
>>>
>>> TIA,
>>>  -sen
>>>
>>> _______________________________________________
>>> Maxima mailing list
>>> Maxima at math.utexas.edu
>>> http://www.math.utexas.edu/mailman/listinfo/maxima
>>>   
>>>       
>
> _______________________________________________
> Maxima mailing list
> Maxima at math.utexas.edu
> http://www.math.utexas.edu/mailman/listinfo/maxima
> .
>
>   
Following the earlier discussion in this thread (thanks fo RJF and 
Barton), I wrote the following function which relates fpprec and ?fpprec.

(%t112) fp_bits(n):=floor(log(bfloat(10)^n)/log(bfloat(2)))+3
(%o112) [%t112]
(%i113) fpprec: 1000;
Evaluation took 0.0000 seconds (0.0000 elapsed) using 3.977 KB.
(%o113) 1000
(%i114) fp_bits(1000);
Evaluation took 1.0900 seconds (1.0900 elapsed) using 90.897 MB.
(%o114) 3324
(%i115) ?fpprec;
Evaluation took 0.0000 seconds (0.0000 elapsed) using 48 bytes.
(%o115) 3324
(%i116) fpprec:200;
Evaluation took 0.0000 seconds (0.0000 elapsed) using 664 bytes.
(%o116) 200
(%i117) fp_bits(fpprec);
Evaluation took 0.0300 seconds (0.0200 elapsed) using 3.884 MB.
(%o117) 667
(%i118) ?fpprec;
Evaluation took 0.0000 seconds (0.0000 elapsed) using 48 bytes.
(%o118) 667

So, apparently
fp_bits(fpprec) = ?fpprec

I checked this for 1 <= fpprec <= 300 with
for i: 1 thru 300 do block(fpprec: i, if (fp_bits(fpprec) # ?fpprec) 
then print("false"));

That was enough for me.

Of course, one could check the source code for bfloat to verify this in 
general.

-sen