American Citizen on Thu, 17 Apr 2025 03:43:47 +0200


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: doing radix conversions in floats


Bill:

Thanks for the quick right up for hexadecimal numbers. I adapted your procedures into working with general radix numbers base 2 to base 16. (it could be expanded, say up to base 35 or so)

Here's the code I came up with:

{R2D(N,rdx=16)=
my(m,a,b,s,t,u);
m=Map(["0",0; "1",1; "2",2; "3",3; "4",4; "5",5; "6",6; "7",7; "8",8; "9",9; "a",10; "b",11; "c",12; "d",13; "e",14; "f",15]);
[a,b]=strsplit(N,".");
if(rdx==16,
 u=eval(Str("0x",a)) + eval(Str("0x",b))/rdx^#b*bitprecision(1.,4*#b);
 return(u);
);
a=Vecrev(strsplit(a));
b=strsplit(b);
\\ convert integer part
s=0;
for(i=1,#a,s+=mapget(m,a[i])*(rdx^(i-1)));
t=0;
for(i=1,#b,t+=mapget(m,b[i])/(rdx^i));
u=s+t*1.0;
return(u);
}
addhelp(R2D,"R2D(n,{radix=16}) converts radix number into a decimal at current bit precision");

{D2R(N,rdx=16)=
my(m,a,b,c,d,A,s,t,u);
m=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
a=truncate(N);
b=N-a;
if(rdx==16,
  s=strprintf("%x.%x",a,b*rdx^((bitprecision(b)+exponent(b))\4));
  return(s);
);
A=digits(a,rdx);
s="";
for(i=1,#A,s=strexpand(s,m[A[i]+1]););
r=ceil(default(realprecision)*log(10)/log(rdx));
t="";
for(i=1,r,
 c=b*rdx;
 d=truncate(c);
 b=c-d;
 t=strexpand(t, m[d+1]);
);
u=strexpand(s, ".",  t);
return(u);
}
addhelp(D2R,"D2R(n,{radix=16}) converts a decimal number into a radix number at current bit precision");

This seems to work fairly well.

- Randall


On 4/16/25 01:22, Bill Allombert wrote:
On Tue, Apr 15, 2025 at 11:42:11PM -0700, American Citizen wrote:
Has anyone ever written a radix conversion program for converting decimal
floats to other radixes such a base 16?

I wrote a dec2hex and hex2dec for integers which seems to work, if I
stipulated that the output of the numbers in other bases than 10 is a
delimited string "0xnnn".
In GP you can do
? strprintf("0x%x",7123456)
%89 = "0x6cb200"
? eval("0x6cb200")
%90 = 7123456

I post the code for both below, but ask if anyone has come up with radix
conversions to the right of the decimal point (and in the current working
precision of gp-pari) ?

For example the square root of 2 to 39 digits is
1.41421356237309504880168872420969807857 but the equivalent base 16
representation is 1.6a09e667f3bcc908b2fb1366ea957d3e3adec1751277509a when I
make an attempt to have the equivalent hexadecimal number.
You can start with something like

d2h(x)=my(f=frac(x));strprintf("%x.%x",truncate(x-f),f*16^((bitprecision(f)+exponent(f))\4))
h2d(s)=my([a,b]=strsplit(s,"."));eval(Str("0x",a))+eval(Str("0x",b))/16^#b*bitprecision(1.,4*#b)

? d2h(sqrt(2))
%123 = "1.6a09e667f3bcc908b2fb1366ea957d3"
? h2d(%)
%124 = 1.4142135623730950488016887242096980785

Cheers,
Bill