
Joined: Feb 2003
Posts: 2,812
Hoopy frood

OP
Hoopy frood
Joined: Feb 2003
Posts: 2,812 
Dear Khaled,
I've been playing with the new bigfloat features of the two recent betas, but I am slightly confused by the decision to arbitrarily truncate numbers to 30 decimal places when mIRC is capable of 50 digit precision. Wouldn't it make more sense to truncate to a number's largest bit precision, as determined by the bit depth of the whole number (left and right side of the decimal point)?
That is, if you have a number with 0 on the left side of the decimal point, you can have 50 digits of precision on the right side. If you have 20 digits left of the decimal point, then only 30 on the right side. If 30 on the left of the decimal point, then only 20 on the right.
For a visual demonstration, try running this single line script in the editbox.
//var %i = 0  while (%i <= 55) { var s %pi.bf = $calc($pi * 10 ^ %i)  inc %i }
Above you see precision building for the first 20 iterations until decimal place truncation automatically occurs. Instead of the arbitrary truncation of 30, it had ought to start at 50 positions to allow for maximal precision. No?
Last edited by Raccoon; 29/10/22 09:08 PM.
Well. At least I won lunch. Good philosophy, see good in bad, I like!




Joined: Jan 2004
Posts: 2,075
Hoopy frood

Hoopy frood
Joined: Jan 2004
Posts: 2,075 
I don't understand how the float fractions work very well, but here it looks like the 50 digits comes from the length of the fraction assigned to $pi, which was arbitrarily chosen, and mIRC is capable of more.
You can use this alias or some other variable containing more digits of PI than 50, and you'll get more 'precision' from your multiplication. Here's a modification of your alias for a random fraction that looks like $calc can see 314 digits of precision within internal calculations.
//var s %len 314 , %a 0. $+ $regsubex(foo,$str(x,%len),/x/g,$r(0,9)) , %i 0  while (%i <= %len) { var s %pi.bf = $calc(%a * 10 ^ %i)  inc %i }
If you want, you can get 200 digits of precision from this identifier:
alias pi2 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196
The only thing that might change with $pi is that the 50th digit is a zero so it doesn't help the outcome. Plus, the next 2 digits of pi after that are '58', so a more accurate rounding would either change that 0 to a 1, or add some more digits until arriving at a nonzero digit where the following digit is 04.
Since mIRC doesn't have an 'antilog' function that reverses the result of $log() to find the original number, I have an $e identifier...
alias e return 2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992181741359662904357290033429526059563073813232862794349076323382988075319525101901157383418793070215408914993488416750924476146066808226480016847741185374234544243710753907774499206955170
That can be used like
//var s %a.bf $calc( 1  1/ $e)
And hey, I have a trailing zero in my fraction too.




Joined: Feb 2003
Posts: 2,812
Hoopy frood

OP
Hoopy frood
Joined: Feb 2003
Posts: 2,812 
Huh, neat!
But yeah, truncation is still an arbitrary 30 digits right of the decimal point.
I think it'd be swell if mIRC either automatically determined the bit depth of the input values being fed in, or gave us the option to specify "/bigfloat 200 [onoff]" or both.
Well. At least I won lunch. Good philosophy, see good in bad, I like!




Joined: Dec 2002
Posts: 5,254
Hoopy frood

Hoopy frood
Joined: Dec 2002
Posts: 5,254 
Above you see precision building for the first 20 iterations until decimal place truncation automatically occurs. Instead of the arbitrary truncation of 30, it had ought to start at 50 positions to allow for maximal precision. No? $pi contains 50 decimal places, as requested by maroon, to allow for enough precision for the default maximum of 30 decimal places that mIRC returns for bigfloat calculations. If I extend the maximum returned by calculations to 50 decimal places, I would need to extend $pi to 70 decimal places. And so on. NASA uses 15 digits of PI for most calculations. At most 37 digits of PI are needed to relate the size of the known universe to that of a hydrogen atom. 30 decimal places seems to be a reasonable limit for most uses. What calculation are you performing that would require 200 decimal places? :] That said, I am a little disappointed that %pt.bf $calc(0.0000000000000000000000000000000000000000000054) is returning 0 seconds for Planck Time. I mean, how am I going to determine my dog's next feeding time with that kind of inaccuracy? I'll be adding a /bigfloat dN switch to my todo list to allow you to set the required number of decimal places. I am still working on stabilizing bigfloat support, so this may not be added just yet. However, note that increasing the number of significant digits/decimal places that the MAPM library uses/returns decreases calculation speed significantly, so it is not something you should do unless you need it.




Joined: Feb 2003
Posts: 2,812
Hoopy frood

OP
Hoopy frood
Joined: Feb 2003
Posts: 2,812 
NASA uses 15 digits of PI for most calculations. At most 37 digits of PI are needed to relate the size of the known universe to that of a hydrogen atom. I don't know anything about that... but this is still fun! ; /frac  $frac  /frac 3.14  $frac(3.14)  $frac().ticks
frac {
; requires mIRC 7.72 bigfloat
var %ticks = $ticks
if (!$isid) window asdDoe2izj100000M t0,31,62 @frac $iif(!$window(@frac),1 1 900 600)
clear @frac
if (!$1) /tokenize 32 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
var %whole = $int($1)
var %decim.bf = $calc($1)
var %min_numer = %whole, %min_denom = 1
var %max_numer = %whole + 1, %max_denom = 1
var %mid_numer, %mid_denom, %frac, %frac.bf, %delta.bf
while (1) {
%mid_numer = %min_numer + %max_numer
%mid_denom = %min_denom + %max_denom
%frac = %mid_numer $+ / $+ %mid_denom
%frac.bf = %mid_numer / %mid_denom
%delta.bf = %frac.bf  %decim.bf
if (!$isid) {
aline @frac $gettok(%delta.bf,2,46) $+ $chr(9) $+ %delta.bf $+ $chr(9) $+ %frac $+ $chr(9) $+ %frac.bf
}
if (%delta.bf < 0) {
%min_numer = %mid_numer
%min_denom = %mid_denom
}
elseif (%delta.bf > 0) {
%max_numer = %mid_numer
%max_denom = %mid_denom
}
else {
if (!$isid) echo a done $calc($ticks  %ticks) ms. %frac = %frac.bf
if ($prop == ticks) return $calc($ticks  %ticks)
return %frac
}
}
; https://stackoverflow.com/a/5128558/8805628
} ; Raccoon 2022
I'll be adding a /bigfloat dN switch to the next beta to allow you to set the required number of decimal places.
However, note that increasing the number of significant digits/decimal places that the MAPM library uses/returns decreases calculation speed siginifcantly, so it is not something you should do unless you need it. Thank you =^_^=
Well. At least I won lunch. Good philosophy, see good in bad, I like!




Joined: Jan 2012
Posts: 226
Fjord artisan

Fjord artisan
Joined: Jan 2012
Posts: 226 
NASA uses 15 digits of PI for most calculations. At most 37 digits of PI are needed to relate the size of the known universe to that of a hydrogen atom. 30 decimal places seems to be a reasonable limit for most uses. What calculation are you performing that would require 200 decimal places? :] That said, I am a little disappointed that %pt.bf $calc(0.0000000000000000000000000000000000000000000054) is returning 0 seconds for Planck Time. I mean, how am I going to determine my dog's next feeding time with that kind of inaccuracy? Off topic: Sorry, I just can't stop myself from laughing at these funny jokes! Probably, Mr. Raccoon plans to make calculations in mIRC for the development and creation of his own "Time Machine", not otherwise. Wow! Let's go, Back to the Future... to 1995!Nevertheless, thanks anyway for the additional and useful change that will be made in the near future.




Joined: Jan 2004
Posts: 2,075
Hoopy frood

Hoopy frood
Joined: Jan 2004
Posts: 2,075 
Just to be clear, does dN mean that changes the length of $calc(1/3) similar to the $calc(math,N) I had suggested, or just changes the precision used inside the 30 digit display? I intended the $calc(,N) to only be something that affects the display length and not the actual precision of of the actual calculation.  I didn't ask for 50 specifically, just that $pi had more digits than the output of 30 it seems reasonable that  in BF mode where fractions are returned with 30 digits, that the 20 digit fraction of $pi should be lengthened to have more digits than that.
... would have 100 digits.
And no I don't think the fraction needs to be that long, but should probably be at least slightly more than the 30 $calc can return. I'm not caring so much about the length of fractions for tiny numbers in .bf results except for things like $log2(2) not giving me 1  as I am about the integer portion of big results. If everyone else wants to shorten $pi to be slightly longer than the default 30 digit precision, or shorten from the backwardscompatible length of 20 down to NASA's 15, I'm golden with that, as long as they accept the problems I mention below. To further clarify my reasoning... When $pi is used in a calculation, it seemed reasonable that any imprecise fraction should not be caused by $pi itself, such as where $calc($pi + 1/10^30) shouldn't have a lot of zeroes in the middle causing a 30digit result that's smaller than the 30digit value for truePI. Because $calc was able to make use of longer inputs, that was probably the reasoning for $pi originally having 20 digits. I was just using the same reasoning that $pi in .bf mode should have 'more than 30' as the number of digits it has. Whether that's adding +20 to the 30 digits or just +3 I have no opinion, other than the final useddigit should probably be rounded up if the next unused digit is 5orgreater. I can't think of any examples where $pi is used as the base for exponentiation, offhand, but that does apply to the 'e' constant for which I gave an absurdly long length. There is no 'antilog' function from which to obtain 'e', and any such result would have rounding issues also. So I had made something like $e to return that constant so I could use $e in calculations where 'e' is commonly used as both a multiplier and the base for an exponent that's obviously more sensitive to precision than multiplication: //var s %e1.bf $calc(2.001^11), %e2.bf $calc(2.002^11), %m1.bf $calc(2.001*11), %m2.bf $calc(2.002*11) * Set %e1.bf to 2059.292202282269582789281320220022 * Set %e2.bf to 2070.64097859678712285217803266253 * Set %m1.bf to 22.011 * Set %m2.bf to 22.022 ... and obviously a shorter length of the $pi fraction would shorten the result of multiplications involving integers that aren't a power of 10. If only 6 digits of precision is needed, the 355/113 approximation can get that for you: //var s %a.bf $calc(355/113  $pi) * Set %a.bf to 0.000000266764189062422312368932 I admire what NASA did in the 60's and 80's. They went to the moon using computers weaker than our phones, and sent probes out of the Solar System where there's no Geek Squad to come out to fix things that go wrong.




Joined: Jan 2004
Posts: 2,075
Hoopy frood

Hoopy frood
Joined: Jan 2004
Posts: 2,075 
For those who can't get enough of long fractions, there's a whole site dedicated to them. Should you need to satisfy your withdrawal symptoms, you can get your fix at oeis.org They have hundreds if not thousands of pages, with each of them dedicated to a different math constant or a sequence of integers. For example, if someone needs to make their own $pi2 alias identifier with a whole lot of precision, the page for $pi has links to where you can find more than you can possibly use. https://oeis.org/A000796So far there are so many trillions of digits of PI known, that most people don't have a hard drive that can store them all, and people are still calculating more of them. Blowfish uses a little more than 4000 digits of the PI fraction to initialize some data. There wasn't anything special about PI that makes Blowfish magically better, it was just an arbitrary choice to find something nonzero to start out with. When people need to initialize some variables semirandomly but don't want to explain how they came up with the numbers they ended up using, they just pick something like PI. Like when they created the hashes like $sha1, they needed to have some variables being initialized to 'something', so they just picked a bunch of square roots and used digits from each. If you can think of a math constant, they've got a page for it, and it probably has thousands of digits of its fraction. There's lots of places in the real world that turn out to be related to some of these fraction constants, and some of them end up having unusual relationships to each other. For exampe, If you want to cut a paper in half so that the ratio of total/longpiece is the same ratio as longpiece/shortpiece, the ratio would be the golden ratio that is 1.6180339... If you take this number and square it, it's the same as adding +1 to it. If you take the inverse 1/golden, that's same as subtracting 1 from it. This turns out to be related to the Fibbonacci series, where each number in the series is the total of the previous 2 numbers. As you keep coming up with new numbers in the series, if you divide it by the previous number, the fraction gets closer and closer to... the golden ratio //var s %fib1.bf 1, %fib2.bf 2 , %i 1  while (%i < 100) { echo ag %i : %fib2.bf / %fib1.bf = $calc(%fib1.bf / %fib2.bf)  var %temp %fib2.bf, %fib2.bf %fib2.bf + %fib1.bf, %fib1.bf %temp  inc %i } To get a thousand digits of this neverending fraction without finding thousands of Fibbonacci numbers, you can instead find it another way, though not so simple either. The golden ratio is the same as $calc( ($sqrt(5) +1) /2), but of course for that you'd need a way to find a thousand digits for that square root. But they've got ways to calculate that too. The natural logarithm 'e' 2.718... used by the $log identifier is something else that pops up in a lot of places. Like if you have compound money interest, the shorter you make the time interval, the closer the interest rate approaches a number that can be calculated using 'e'. It also shows up in a lot of randomness. If you ask 1000 times for a random number from $rand(1,1000), you're not going to get each of the 1000 numbers showing up 1 time. On average, what fraction of the 1000 numbers will not come up during those 1000 outputs? It's close to 1/e, and the larger number you use in place of both 1000's, the closer it gets to 1/e. What portion of numbers show up exactly 1 time? Also 1/e. What portion shows up exactly 2 times? 1/2e. The formula to find the chance that something shows up exactly N times uses 'factorial, which is that number multiplied by all the numbers below it. i.e. 5 factorial is 1*2*3*4*5. So that means the chance of a number showing up exactly 3 times is 1/(1*2*3*'e'). So this SUM will eventually reach 100% //var s %e 2.718281828459 , %factorial 1 , %i 0, %sum.bf 0  while (%i < 100) { inc s %sum.bf $calc(1 / (%e * %factorial))  inc %i  var %factorial %factorial * %i } Oh, but it went over 100%. But that's because the value for '%e' didn't have enough digits. But if using enough digits, and have enough precision when dividing, then it would be on the underside of 1.0, and then you'd need to repeat more times to get the fraction closer to 100%.




Joined: Feb 2003
Posts: 2,812
Hoopy frood

OP
Hoopy frood
Joined: Feb 2003
Posts: 2,812 
For those who love IRC trivia games, there are all sorts you could buy from Milton Bradley. tl;dr
Well. At least I won lunch. Good philosophy, see good in bad, I like!




