Re: Phix, numbers, printf, log10

new topic     » goto parent     » topic index » view thread      » older message » newer message

Thank you for the %e fix, I'll try it out tomorrow.

petelomax said...

Note that for obvious reasons printf() works digit-by-digit then rounds, so always matching round() is simply not an option.

I am doing this, rounding the value to the specified number of decimal digits before calling sprintf():

-- atom r is the number to be printed 
-- integer fmt is the number of decimal digits 
-- string rf is a temporary variable 
-- string rr is the formatted result (yes, bad habit of mine, to use minimalistic variable names) 
 
r = round(r, power(10, fmt)) 
rf = "%1." & sprint(fmt) & "f" 
rr = trim(sprintf(rf, r)) 

I'm not sure if it's 100%, but I think it is a significant improvement.

I've also written a little function to work around the fact that power() uses logarithms, and therefore doesn't always give integer results for power(a, b) even if a and b are integer — seems to work fine (updated March 9):

function power_int(atom a, atom b, integer maxb = 59) 
 
	atom p 
	p = power(a, b) 
	if integer(a) and integer(b) and b > 0 then           -- if result should be integer ... 
		if not integer(p) then                        -- ... but isn't 
			if abs(p) < 1e18 and b <= maxb then   -- maxb limit to avoid using too much time for this, not sure if it is necessary 
				p = a                            -- power(2, 60) is > 1e18, therefore 59 is the highest possible exponent 
				for j = 2 to b do 
					p = p * a 
				end for 
			end if 
		end if 
	end if 
	return p 
end function 

? power(3, 18)
? integer(power(3, 18))
? power_int(3, 18)
? integer(power_int(3, 18))
387420489.0
0
387420489
1

What I still find a bit troubling, though, is that 8.98 * 100 is not an integer. In the upcoming 64-bit version of Hypatia I'll use a function (which can be disabled) which rounds non-integer values to 17 significant digits, and if that is integer, then it replaces the original value — meaning, everything very close to integer is considered to be intended to be integer — this also resolves the 8.98* 100 issue well enough for me.

I think that, with %e working correctly, I have all I need for all practical purposes. Still have to be wary, though.

Robert

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu