I admit, this one (https://masm32.com/board/index.php?topic=10754.msg120275#msg120275) was kinda shitty and it wasn't fully functional.
But now this one is the real thing. Nearly...
Hit me up @ https://github.com/SilverfoxSystems/Hyper (https://github.com/SilverfoxSystems/Hyper)
& http://silverfox.systems/Hyper/ (http://silverfox.systems/Hyper/)
What numeric type is that?
It's a mixture of a String and a floating-point number. It consists of Int64 array and an Int32 which describes the lowest exponent.
EDIT:
"Adaptive float" would maybe describe it best
What are range and precision of that format?
As far as the mentioned Int64 array's size goes, this is how big the mantissa can be.
I.E.
if initialized as
New Hyper(5000,-5000) (low and high "exponents")
then it'd have buffer(mantissa) of length of 10000 * 8 bytes.
The Int32 mentioned describes number of starting QWORD or as I call it, Exponent64 or exp64 in my descriptions.
In fact, the number used is called precision which is the negated LOWEST exp64 .
So the precision is enormous - as many bits there are in approx. 8 * 2GB with the mentioned Int32 offset.
You can have an entire RAM describing a single number :)
Ok. It's an "arbitrary precision" format.
Precision depends on mantissa, not exponent. Range depends on exponent.
:thumbsup:
i agree :smiley: never heard of that format, thanx 4 clearing it out
only thing that maybe differs from others is that it works on balanced numeral system (with base 2^64) - some advantages: sign bit isn't needed, every 64th bit is negative => no rounding error + no need of filling bits when expanding mantissa's size
@ i Z !
the one thing that bothers me is the restrictive license
Quote from: jack on October 16, 2023, 09:45:57 PM@ i Z !
the one thing that bothers me is the restrictive license
it lets you do whatever with it. only not making money off my hard work :)
or you had something specific in mind?
Quote from: i Z ! on October 16, 2023, 11:07:30 PMor you had something specific in mind?
not really, I also have dabbled in writing my own multi precision arithmetic routines, just for fun.
what number base do you use for your routines?
i Z !
this the kind of license that would acceptable to me, it's from https://bellard.org/libbf/
Quote/*
* Tiny arbitrary precision floating point library
*
* Copyright (c) 2017-2020 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
Quote from: jack on October 17, 2023, 12:21:36 AMwhat number base do you use for your routines?
Quote from: i Z ! on October 16, 2023, 04:44:49 PMit works on balanced numeral system (with base 2^64)
Quote from: jack on October 17, 2023, 12:30:47 AMQuote* Permission is hereby granted, free of charge, to any person obtaining a copy...
...
...
...
Sorry but I get lost before finishing reading it :smiley:
EDIT this is a MIT licence (according to website), which allows commercial use, so i'm not alright with that
suit yourself, MIT is one the most simplest licenses, if you can't understand that then I doubt your ability to code a decent MP library
Quote from: jack on October 17, 2023, 02:19:44 AMsuit yourself, MIT is one the most simplest licenses, if you can't understand that then I doubt your ability to code a decent MP library
hah, give it a go mr lawyer
it's as 'decent' as it gets :)
Quote from: jack on October 17, 2023, 02:19:44 AMsuit yourself, MIT is one the most simplest licenses, if you can't understand that then I doubt your ability to code a decent MP library
IMHO before accusing others to be unable to code, you should start coding yourself
I have
Quote from: jack on October 17, 2023, 12:21:36 AMnot really, I also have dabbled in writing my own multi precision arithmetic routines, just for fun.
It's fun that's for sure, I think I enjoyed writing it the most from all my projects 'til now
Quote from: jack on October 17, 2023, 02:19:44 AMsuit yourself, MIT is one the most simplest licenses, if you can't understand that then I doubt your ability to code a decent MP library
My friend, it's
you who seems not to understand: the author doesn't want to grant free use for commercial purposes. What don't you get about that?
It's got nothing to do with simplicity.
ok, here's an example code (also updated on GitHub), if it makes it more attractive :smiley:
Dim a As New Hyper(5, 0) ' initialize an integer with 6 * 64 bits
Dim b As New Hyper(-1, -4) ' float with 4 * 64 bits
a(5) = 50000 : a(3) = 50000 ' this is 50000*(2^64)^5 + 50000*(2^64)^3
b(-1) = -50000 : b(-3) = 50000 ' = -50000*(2^64)^(-1) + 50000*(2^64)^(-3)
Dim precision% = 914 'we need high precision since we're dividing with a multiple of 5, which results in a repetitive non-integral value in binary system
Dim c As New Hyper(0, -precision)
c(0) = 1
'get value of 1e-60 into c
For i = 1 To 4
c.Divide(10 ^ 15, precision)
Next
Hyper.maxDigitsInString = 255 'this number gets aligned to a multiple of 18 in the decimal ToString method's output
Console.WriteLine(c) : Console.WriteLine()
Console.WriteLine(a)
Console.WriteLine(a * c) : Console.WriteLine()
Console.WriteLine(b)
Console.WriteLine(b * c) : Console.WriteLine()
Console.WriteLine(a * b)
Console.WriteLine(a * b * c)
Console.ReadKey()
' output:
' 0.000001 e-54
'
' 106799351796 045504119751085308 477605730449081204 601972535543869862 271369609837145273 371306072473600000
' 106799351796045504119751085308477605730449.081204601972535543869862271369609837145273371306072473600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
'
' -0.00000000000000271050543121376108501863200217485427855648766544433773861485559801116144097204447722403690606963057073306918549243470919528455062639908657029508276536944322288036346435546875
' -0.00271050543121376108501863200217485427855648766544433773861485559801116144097204447722403690606963057073306918549243470919528455062639908657029508276536944322288036346435546875 e-72
'
' -289480223093290 488558927462521719 769633174961664101 410098643960019782 824099837500000000
' -289480223093290488558927462.521719769633174961664101410098643960019782824099837500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
So how do we know that result is correct?
(Ha ha, just kidding ...)
oh, you mean for a * b... we assume that :smiley:
But doing that makes an ASS out of U and ME ...
No it only presents us AS SUM of E :smiley:
My thinking is, if it multiplies by 1e-60 with no error, which is in binary quite an odd repetitive number, then it has no alibi to fail with anything else
But seriously, have you actually checked those results? (I have no friggin' idea how you would even do that. Calculator's not gonna help you here.)
Kind of like the satellite, the Mars Climate Orbiter that burned up because someone didn't check their number system (metric vs. "imperial"). Or something like that.
I suppose you could feed the results back into another program which does the inverse operation that was done, see if you get the original values?
i tried adding this code
c = a * b
a = New Hyper(0, 0)
While c.IsNegative '.IsNotZero
c.Subtract(b)
a.Incr()
End While
Console.WriteLine(a)
as you can imagine, that WHILE block was taking quite a WHILE :smiley: so I stopped it after a few minutes
Quote from: NoCforMe on October 18, 2023, 07:31:52 PMI suppose you could feed the results back into another program which does the inverse operation that was done, see if you get the original values?
When I was writing the procedure for division by Int64, i think i knew how to include other int64 digits while performing the operation. At the time I thought to myself, it won't be needed... Then I later tried to implement it another way but without success.
I have to write at least the 1/x function
Quotethen it has no alibi to fail with anything else
... unless you try to compute the circumference of a circle from that diameter (or the opposite).
Quote from: raymond on October 19, 2023, 02:10:20 AMQuotethen it has no alibi to fail with anything else
... unless you try to compute the circumference of a circle from that diameter (or the opposite).
'fail' was referring to multiplication. You mean because there's no pi? You'd need to calculate pi first... after you wrote the procedure for sqrt :)
Quote... after you wrote the procedure for sqrt :)
:joking: :thumbsup:
@NoCforMe @raymond
I think I have (at least partial) solutions to both of your questions - New(string) initializer added in the new version, so now you can input just about any number in decimal format (updated on GitHub).
I already tried it with 1000 decimals-long pi value and it worked well. The thing was that this horsesh*t of a Git interface in VS made that code to be deleted. It said "you can't push this repo because bla bla... use Sync to...". Then I clicked Sync, but it doesn't say which way it will sync, then, with no warning deleted the entire local solution. Luckily, it was only a few lines of code. Anyway I think I learnt how to deal with GitHub now.
GitHub = another thing I sincerely hope I never have to deal with in my lifetime ...
After nearly a week,
32 clo(w)ners cloned the git repo 86 times. Practically an empty project...
TWO people in total downloaded the actual library, but the previous version... ;)
I'm writing an installation app for it. Not because I'd expect more people to use it, but just for the heck of it :)
I had to refresh a bit about handling the registry entries...
Don't worry, my OS survived the installer tests :azn:
I also tested it with Windows App Cert Kit - Passed with warnings
https://marketplace.visualstudio.com/items?itemName=SilverfoxSystems0.Hyper (https://marketplace.visualstudio.com/items?itemName=SilverfoxSystems0.Hyper)
hi i Z !
in what language was the Hyper dll written ?
hi Jack, in VB.NET
Quote from: i Z ! on November 01, 2023, 05:59:43 AMhi Jack, in VB.NET
Attention, don't click the link. The new improved version of the SMF forum software adds links to known web extensions like garbage.net or garbage.inc, so you may randomly end up with strange pages like Windows.inc
I learnt to avoid that trap by using another "i": Windows.ìnc - no link :biggrin:
thank you jj :smiley:
thank you i Z !, btw it appears that your dll is debug build, you can't use it to compile release test-code :smiley:
PS I don't like installers, if it can be helped I would rather have zip archive
@i Z !
here's my algorithm for MP division in pseudo code
function fpinverse(m as Hyper, precision as long) as Hyper
dim x as double
dim i, lim, ex, prec as long
dim as Hyper r, r2, one, n
n = m
lim = log(precision*0.0625) * 1.5 ' 1.5 = 1/ln(2) + a little extra
' get the most significant digits of m into x without the exponent, because a Hyper number's exponent can quickly exceed the range of double
' get the exponent in base 10 of m into ex
If x = 0 Then print "Division by 0": return r 'Exit Function
' the following is to avoid the pitfall when m is very close to 1, e.g. 0.999999999...
If x = 1 andalso ex=0 Then
r=Hyper("1")
return r
elseif x=1 then
x=10
ex-=1
end if
ex=(-1)-ex 'in your case probably ex = -ex
x=1/x
r=Hyper(x)
r.exponent=ex
one=1
r2=r
prec=8 'start with precision 8 (it's multiplied in the loop)
for i=1 to lim
prec=2*prec-1
r2=Hyper_mul(n,r, prec)
r2=Hyper_sub(one, r2, prec)
r2=Hyper_mul(r, r2, prec)
r=Hyper_add(r,r2, prec)
next
return r
End Function
function Hdivide(n as Hyper, m as Hyper, precision as long) as Hyper
return n * fpinverse(m, precision)
end function
Quote from: jack on November 01, 2023, 06:19:08 AMthank you i Z !, btw it appears that your dll is debug build, you can't use it to compile release test-code :smiley:
PS I don't like installers, if it can be helped I would rather have zip archive
no bother, I'm happy to see someone engaging in my lib :smiley:
It should be in release, what I only found was that
Enable the Visual Studio hosting process option is still on. I'll uncheck that and we'll see if it helps.
I'm also gonna provide info on calls to native add, sub, mul and div procedures, so that you can begin the operation where required... I only need to decipher which argument means what :smiley: , 'cause i was making some changes and i need to make sure that i give the correct data. Probably later in the day.
I checked your code, it looks convincing, ile try it out. While writing this post, i also found that i forgot to write proc's for adding/subtracting an Int64, next version will have them.
Besides that a direct conversion Double-->Hyper isn't supported(i nearly got it, but then abandoned debugging), I'd point out one thing:
The 'r2' block should be written as
r2 = n * r
r2.Subtract(one)
r2.Multiply(r)
r.Add(r2)
(precision can only be set in Divide op)
thanks JJ for that tip, i corrected it
btw references with examples (http://silverfox.systems/Hyper/Descriptions/references.aspx) are also available now
Hi All,
QuoteAttention, don't click the link. The new improved version of the SMF forum software adds links to known web extensions like garbage.net or garbage.inc, so you may randomly end up with strange pages like Windows.inc
I learnt to avoid that trap by using another "i": Windows.ìnc - no link :biggrin:
Yes,.. this was discussed here a while ago, as well as on the SMF Support Forum.
I will re-visit the topic to see if anything has been resolved.
There may be a Mod' to alter the hyperlink behaviour.
Quote from: jj2007 on November 01, 2023, 06:07:48 AMI learnt to avoid that trap by using another "i": Windows.ìnc - no link :biggrin:
Apparently quotes also limit the automatic hyperlink: "windows.inc"
v1.1.0 (https://marketplace.visualstudio.com/items?itemName=SilverfoxSystems0.Hyper)
- A bug in the Add procedure has been found, squashed and burnt alive
- Decimal exponent now supported in the input string, i.e. New Hyper("123.221e-5510")
- Add(Int64, Exp64) function added to perform addition on a single Digit.
- Incr, Decr operations added
- Intellisense descriptions now (finally) work
Quote from: jack on November 01, 2023, 06:19:08 AMPS I don't like installers, if it can be helped I would rather have zip archive
I see, we'll see :)
Quote from: i Z ! on November 01, 2023, 07:15:38 PMbtw references with examples (http://silverfox.systems/Hyper/Descriptions/references.aspx) are also available now
Good, but even better would be a complete example that builds with the Masm64 SDK :thumbsup:
Quote from: i Z ! on November 02, 2023, 01:21:43 PMv1.1.0
Jotti reports it as Trojan.MSIL.Crypt (https://virusscan.jotti.org/en-US/filescanjob/u4ynl3ift8). Nonetheless I tried to run the installer and got a few errors, see below (Win7-64). Re
Access to path 'iZ!' denied.: I created C:\iZ! manually, no problem, but the installer still complains.
QuoteInformation on how to invoke JIT (Just-In-Time) debugging instead of this window
is given at the bottom of the message.
************** Exception text **************
System.UnauthorizedAccessException: Access to path 'iZ!' denied.
in System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath).
in System.IO.Directory.InternalCreateDirectory(String fullPath, String path, Object dirSecurityObj, Boolean checkHost)
in System.IO.Directory.InternalCreateDirectoryHelper(String path, Boolean checkHost)
in Install_Hyper_Data_Type.Form1.inst()
in Install_Hyper_Data_Type.Form1.InstallBtn_Click(Object sender, EventArgs e)
in System.Windows.Forms.Control.OnClick(EventArgs e)
in System.Windows.Forms.Button.OnClick(EventArgs e)
in System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
in System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
in System.Windows.Forms.Control.WndProc(Message& m)
in System.Windows.Forms.ButtonBase.WndProc(Message& m)
in System.Windows.Forms.Button.WndProc(Message& m)
in System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
************** Assembly loaded **************
mscorlib
Assembly version: 4.0.0.0
Win32 version: 4.8.4110.0 built by: NET48REL1LAST_B
Code base: file:///C:/Windows/Microsoft.NET/Framework64/v4.0.30319/mscorlib.dll
----------------------------------------
Install Hyper Data Type
Assembly Version: 1.0.5.0
Win32 version: 1.0.5.0
Code base: file:///C:/Users/Jochen/Downloads/Install_Hyper_Data_Type.exe
----------------------------------------
Microsoft.VisualBasic
Assembly version: 10.0.0.0
Win32 version: 14.8.3761.0 built by: NET48REL1
Code base: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/Microsoft.VisualBasic/v4.0_10.0.0__b03f5f7f11d50a3a/Microsoft.VisualBasic.dll
----------------------------------------
System
Assembly version: 4.0.0.0
Win32 version: 4.8.4110.0 built by: NET48REL1LAST_B
Code base: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Core
Assembly version: 4.0.0.0
Win32 version: 4.8.4110.0 built by: NET48REL1LAST_B
Code base: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0__b77a5c561934e089/System.Core.dll
----------------------------------------
System.Windows.Forms
Assembly version: 4.0.0.0
Win32 version: 4.8.4110.0 built by: NET48REL1LAST_B
Code base: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System.Drawing
Assembly version: 4.0.0.0
Win32 version: 4.8.3761.0 built by: NET48REL1
Code base: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System.Configuration
Assembly version: 4.0.0.0
Win32 version: 4.8.3761.0 built by: NET48REL1
Code base: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Xml
Assembly version: 4.0.0.0
Win32 version: 4.8.3761.0 built by: NET48REL1
Code base: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
System.Runtime.Remoting
Assembly version: 4.0.0.0
Win32 version: 4.8.3761.0 built by: NET48REL1
Code base: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Runtime.Remoting/v4.0_4.0.0__b77a5c561934e089/System.Runtime.Remoting.dll
----------------------------------------
mscorlib.resources
Assembly version: 4.0.0.0
Win32 version: 4.6.1055.0 built by: NETFXREL2
Code base: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/mscorlib.resources/v4.0_4.0.0_en_b77a5c561934e089/mscorlib.resources.dll
----------------------------------------
System.Windows.Forms.resources
Assembly version: 4.0.0.0
Win32 version: 4.6.1055.0 built by: NETFXREL2
Code base: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms.resources/v4.0_4.0.0_en_b77a5c561934e089/System.Windows.Forms.resources.dll
----------------------------------------
************** Debug JIT **************
To enable JIT debugging, you need to set the value
jitDebugging in the system.windows.forms section of the configuration file
of the application or computer (machine.config).
The application also must be compiled with debugging
enabled.
For example:
<configuration>
<system.windows.forms jitDebugging="true" />
</configuration>
When JIT debugging is enabled, all unhandled exceptions
Quote from: jj2007 on November 02, 2023, 07:41:51 PMGood, but even better would be a complete example that builds with the Masm64 SDK :thumbsup:
I created C:\iZ! manually, no problem, but the installer still complains.
thanks JJ, the lib installs into 64bit %PROGRAMFILES% -> "
C:\Program Files\iZ!\Hyper Data Type\", it puts in the dll, xml(for intellisense), licence.txt and uninstall.exe. It also copies/overwrites
Hyper Core.dllin the
System32 dir, so the native dll is accessible.
I just realized I forgot to change version in the installer itself. So it's still writing registry entries for v1.0.4.0. But that shouldn't be a problem.
Masm64 SDK? I don't know much about it.. Anyway only the algo's for arithmetics can be used from "Hyper Core", I'll soon write the documentation. It would be good I guess to have an entirely native lib too, if someone cares to write it.
Be sure to run it as Administrator, if it doesn't automatically ask you to elevate rights after running it
Quote from: i Z ! on November 02, 2023, 09:42:11 PMBe sure to run it as Administrator, if it doesn't automatically ask you to elevate rights after running it
Why should I run a program as administrator that just gives me a DLL??
Quote from: jj2007 on November 02, 2023, 10:09:56 PMWhy should I run a program as administrator that just gives me a DLL??
To allow it access for registering as a Framework library (in registry) and allow creation of folders and copying into System32 dir (for the mentioned "Hyper Core.dll").
hi iZ!
if I were you, I would write the DLL in C, I wrote some MP code in FreeBasic and in C and just now in VB.net
I did a simple test, set the precision to 51200 and then
n = str2fp("7." + StrDup(precision, "7"))
m = str2fp("9." + StrDup(precision, "9"))
m = n / m
m = Sqr(m)
timing of the functions in red not counting conversions
VB.net in release build took .53 seconds
FB took .12 seconds
C took .03 seconds
but since this is an asm forum, why not write your code in masm?
or maybe in MasmBasic https://masm32.com/board/index.php?board=57.0 (https://masm32.com/board/index.php?board=57.0)
Quote from: jack on November 03, 2023, 08:57:32 AMhi iZ!
if I were you, I would write the DLL in C
nope, that's a negative - if you were me, you couldn't stand a single line of C code in your projects :smiley:
Quote from: jack on November 03, 2023, 08:57:32 AMn = str2fp("7." + StrDup(precision, "7"))
What does this function do? I thought that C# produces the same code as VB (at least for calling the common functions)
btw, you can now test out your MP Division procedure, since Hyper now does also accept strings as "1.1234
e-50" ... Not the fastest Double->Hyper conversion, but it's good enough for 'proof of concept'
Quote from: i Z ! on November 02, 2023, 10:55:09 PMQuote from: jj2007 on November 02, 2023, 10:09:56 PMWhy should I run a program as administrator that just gives me a DLL??
To allow it access for registering as a Framework library (in registry) and allow creation of folders and copying into System32 dir (for the mentioned "Hyper Core.dll").
I will not allow that. None of my code published here writes to the registry or attempts to change C:\Windows\*
Quote from: jj2007 on November 03, 2023, 08:46:48 PMI will not allow that. None of my code published here writes to the registry or attempts to change C:\Windows\*
Well, I don't think it's possible to register a .NET library in other way than in registry.
Also it writes (into separate registry entries) the uninstall info, so you can uninstall the library under
Settings / Apps & Features What I can offer is only the ability to choose the installation folder and put in there the native dll as well. But then, this folder would have to be put into the PATH variable, which would again require Admin rights
as some of you may know, the art of making a functional installer is making an uninstaller, which self-destructs (you can't do that in any language while .exe is running) and deletes the folder containing it at the end
QuoteAttention, don't click the link. The new improved version of the SMF forum software adds links to known web extensions like garbage.net or garbage.inc, so you may randomly end up with strange pages like Windows.inc
I learnt to avoid that trap by using another "i": Windows.ìnc - no link :biggrin:
NB: Please NOTE, I have 'Fixed' this issue.
I had inadvertently selected a Check-Box in the Admin' controls to Automatically 'link' Posted URL's
This has now been De-selected, so you will need to utilize BBcode tags or the 'Link' Button in the Editor to Post an Actual URL.
Cheers
:smiley:
Quote from: i Z ! on November 03, 2023, 08:41:11 PMQuote from: jack on November 03, 2023, 08:57:32 AMhi iZ!
if I were you, I would write the DLL in C
nope, that's a negative - if you were me, you couldn't stand a single line of C code in your projects :smiley:
Hmm; I see I'm not the only one here ...
Who wants, can now download the native library here (http://silverfox.systems/Hyper/) (@ the main page)
references - native (http://silverfox.systems/Hyper/Descriptions/refsNative.aspx)
Found a relatively quick way to divide. It's approximate, but close enough :smiley:
VB
Option Explicit Off
Imports HyperLib
'!!! For this code to work, because of the numeric methods used, "Skip integer overflow checks" option must be checked in the Advanced compile settings
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Hyper.displayMode = Hyper.displayModeType.inDecimalBase2_64
Hyper.maxDigitsInString = 7 'display range
' input some random numbers for a and d ->
Dim a As New Hyper(-251, -253) 'assign 3 * 8 bytes for a, with its least exponent (2^64)^(-253)
a(-252) = -79786875757656175
a(-253) = 79978687575765619 '
a(-251) = 7978687575765619
Dim d As New Hyper(-444, -444) 'reserve 8 bytes for the divisor
d(-444) = 1 + (2 ^ 53)
d(-5) = 1 + 2 ^ 44 'mantissa automatically gets extended when assigning values at exponents out of current range; now the size of "d" is ((444-5) * 8) bytes
Debug.WriteLine("")
Dim rdiv As Hyper = QuickDivide(a, d)
Debug.WriteLine("=================== result:")
Debug.WriteLine(rdiv)
rdiv *= d
Debug.WriteLine("=================== check:")
Debug.WriteLine(rdiv)
End Sub
Private Function QuickDivide(dividend As Hyper, d As Hyper) As Hyper
Return dividend * ReciprocalVal(d)
End Function
Private Function ReciprocalVal(d As Hyper) As Hyper
precision% = 1444 'number of 64-bit digits to extract. Must be larger than exponent range
precision2% = 222 'may be zero
Dim r As New Hyper(precision, 0) ' New Hyper(0, 0)
Dim bp, r1 As Hyper
hiExp% = d.FindHighExponent
lowExp% = d.FindLowExponent
lowVal& = d(lowExp)
If (lowVal And 1) = 0 Then
Debug.WriteLine("even nr")
'if the least significant bit is 0, then we can help ourselves with dividing/multiplying the dividend, and then the result, by 2^n.
d(lowExp - 1) = 1
lowVal = 1
lowExp -= 1
End If
mq& = GetMagicNr(lowVal)
pos% = lowExp '
d.Round(-pos)
d.PartSize = 0
bp = New Hyper("1")
pos1% = 0
mainloop:
' get the sequence which, when multiplied by divisor, nullifies itself
r1 = New Hyper(pos1, pos1)
r1(pos1) = bp(pos1) * mq
r(pos1) = r1(pos1)
bp -= d * r1
bp.Negate()
pos1 += 1
If pos1 > precision Then GoTo nx
'reciprocal values of large numbers tend to repeat at very large intervals, so we'll be satisfied with our precision
GoTo mainloop
nx:
r1 = r * d
hi% = r1.FindHighExponent
r.Divide(r1(hi), precision2)
r.PartSize = hi + r1.PartSize + r.PartSize + lowExp '.PartSize
d.PartSize = -lowExp
Debug.WriteLine("--=-=-=-=- recip*d:")
Debug.WriteLine(r * d) 'should output close to 1
Debug.WriteLine(r)
Debug.WriteLine("--=-=-=-=-")
Return r
End Function
Private Function GetMagicNr&(a&)
' Magic number or "reciprocal integer" - GET THE 64-BIT NUMBER WHICH, when multiplied by the lowest digit, gives 1 as the remainder of 2^64
' Only for odd numbers.
bt& = 1 'bit tester
d& = a 'bit mask
r& = 0 : i& = 0 : r0& = 0
For i = 0 To 63
If bt And r Then GoTo skip
r += d
r0 = r0 Or bt
skip:
bt <<= 1 : d <<= 1
Next
Return r0
End Function
End Class
Also posted on github (https://github.com/SilverfoxSystems/BigDivide)
P.S.: I recently noticed that full decimal representation has bugs, I removed the
default property from it. Who needs it anyway :)
hello i Z !
I would be interested in testing you HyperLib but there several reasons that prevent that
1: prohibitive licence
2: closed source
3: binary distribution only, and worst, it comes as an installer
Quote from: jack on August 31, 2024, 07:17:02 AMhello i Z !
I would be interested in testing you HyperLib but there several reasons that prevent that
1: prohibitive licence
2: closed source
3: binary distribution only, and worst, it comes as an installer
hi Jack,
points 1. and 2. are not preventing you from testing. For the 3rd, I silently hope that one day, you'll find the courage to just install the bloody thing :) it only takes a split second.
I'm planning to use this library in one of my bigger projects and I need to know whether the calculations are performed correctly 100% . I tested the boundaries, it appears to work well, but you never know :)
iZ!
have you overloaded the basic arithmetic operators?
for example, how would you translate the following code to use your HyperLib ?
and set eps to something like 1e-1000
Dim As Double eps, Pi, x, y
x = 3
y = 1
Pi = x
eps = 1e-15
While (x > eps)
x = x * y / ((y + 1) * 4)
y += 2
Pi += x / y
Wend
Print Pi
tried to compile the test solution found at your Git repo
QuoteSeverity Code Description Project File Line Suppression State Details
Error (active) BC30437 'Public Overrides Function NewFromString(S As String) As Integer' cannot override 'Public Overridable Function NewFromString(S As String) As String' because they differ by their return types. Hyper Test C:\Users\Admin\Desktop\Hyper-master\Hyper Test\Module1.vb 78
if I remove "Overrides" then it compiles but the output are hexadecimal strings, the .toString method makes no difference
if you want the average person to try your Hyperlib then you need friendly input/output, who wants to see a bunch of hex strings?
hey, thanks for trying it out,
Quote from: i Z ! on August 30, 2024, 07:29:57 AMP.S.: I recently noticed that full decimal representation has bugs, I removed the default property from it. Who needs it anyway :)
this is the reason why you can't see decimal by default, but you can change it with
Hyper.displayMode = Hyper.displayModeType.inTrueDecimal
I know it's a bit tricky as you can't be sure about decimal output to do the checks, but you can try inputting pi just as
Dim pi as new Hyper("3.14......") 'string can be of any length
I'm checking your code right now, it shouldn't take too much modification
Quote from: jack on September 15, 2024, 12:14:49 AMand set eps to something like 1e-1000
to do this, I'd use something like
eps.Divide(10^18,precision)
in a loop, after setting it to 1
EDIT:
Actually, Dim pi as New Hyper("1e-1000") should also work (with even aligning the buffer to least possible size as I remember, I'll check)
I am sorry iz! but after all this time your Hyperlib doesn't have enough functionality for me to spend time on
I do my fun programming in FreeBasic which supports function and operator overloading, I wrote function and operator overloads for the LibBF Library (https://bellard.org/libbf/), with that, the little Pi program looks like this
dim shared as long bf_digits = 1000 ' dim and set bf_digits before including bf.bi
#include "bf.bi"
Dim As bf eps, Pi, x, y
dim as double t=timer
x = 3
y = 1
Pi = x
eps = "1e-1000"
While (x > eps)
x = x * y / ((y + 1) * 4)
y += 2
Pi += x / y
Wend
t=timer-t
Print Pi
Print "elapsed time in seconds = ";t
it completes in 0.0076 seconds
output
Quote3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707211349999998372978049951059731732816096318595024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303598253490428755468731159562863882353787593751957781857780532171226806613001927876611195909216420199
try this:
Hyper.displayMode = Hyper.displayModeType.inTrueDecimal
Hyper.maxDigitsInString = 777 'display range
Dim eps, Pi, x As Hyper
prec% = 50
Hyper.QuotientPrecision = prec 'defines for the '/' operator
x = New Hyper("3")
Dim y2& = 1
Pi = New Hyper(x)
eps = New Hyper("1")
For i% = 0 To 90
eps.Divide(10 ^ 18, prec)
Next
While x > eps
x.Multiply(y2)
x.Divide((y2 + 1) * 4, prec)
y2 += 2
Pi.Add(x / y2)
End While
Debug.WriteLine(Pi)
i got
Quote3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930381964428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273724587006606315588174881520920962829254091715364367892590360011330530548820466521384146951941511609433057270365759591953092186117381932611793105118548074462379962749567351885752724891227938183011949129833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132000568127145263560827785771342757789609173637178721468440901224953430146549585371050792279689258923542019956112129021960864034418159813629774771309960518707
with this, but you can play around with precision(s). Anyway, I'm not sure how much the decimal output can be relied upon...
Nice way of getting pi indeed :thumbsup:
if you need only a small number for 'eps', you can do this by
Dim eps as New Hyper(-20,-20)
eps(-20) = 1
and set the (20*64)th bit after the decimal point. This way, the buffer size is only 1 QWORD
iZ!
the point is, make the library function/behave as close as possible as if it were of type double, look how little I had to change to my little Pi program to make it's computations at high precision
Quote from: jack on September 16, 2024, 12:05:27 AMiZ!
the point is, make the library function/behave as close as possible as if it were of type double, look how little I had to change to my little Pi program to make it's computations at high precision
yeah, it is kinda messy to work with Int64s. But it ensures that there's no unnecessary variable copying
Quote from: jack on September 15, 2024, 07:48:26 PMI wrote function and operator overloads for the LibBF Library (https://bellard.org/libbf/), with that, the little Pi program looks like this
Quote from: i Z ! on September 15, 2024, 10:11:18 PMNice way of getting pi indeed :thumbsup:
bellard it's a great programer, I suppose he's the creator of ffmpeg that most persons use today, also qemu, ..., . Also nncp data compression that uses neural network.
Quote from: mineiro on September 16, 2024, 01:23:21 AMQuote from: jack on September 15, 2024, 07:48:26 PMI wrote function and operator overloads for the LibBF Library (https://bellard.org/libbf/), with that, the little Pi program looks like this
Quote from: i Z ! on September 15, 2024, 10:11:18 PMNice way of getting pi indeed :thumbsup:
bellard it's a great programer, I suppose he's the creator of ffmpeg that most persons use today, also qemu, ..., . Also nncp data compression that uses neural network.
alright, useful info. But the pi procedure is something which Jack came up with, isn't it?
I've just noticed that we've got the same result, now I'm more confident in the decimal representation again :) idk, once I "caught it" when it changed the sign at a very small value
Jack, you can add operators I guess, in case you need them. Btw, I could write
x /= (y2 + 1) * 4
Pi += x / y2
, but
x.Divide((y2 + 1) * 4, prec)
Pi.Add(x / y2)
is faster
Quote from: i Z ! on September 15, 2024, 10:11:18 PMAnyway, I'm not sure how much the decimal output can be relied upon...
I really don't understand how you could feel confident about the results being shown in one radix (hex) but not in another (decimal). It's just a matter of character representation, no? Unless you have some kind of conversion routine in there that you're not sure about ...
Quote from: NoCforMe on September 16, 2024, 08:17:17 AMQuote from: i Z ! on September 15, 2024, 10:11:18 PMAnyway, I'm not sure how much the decimal output can be relied upon...
I really don't understand how you could feel confident about the results being shown in one radix (hex) but not in another (decimal). It's just a matter of character representation, no? Unless you have some kind of conversion routine in there that you're not sure about ...
hey noCforme,
yes, quite a lot of computing needs to be done to convert from one another. The hex output shows bits as they are in memory, for decimal I need to convert. I think I'll post the procedures here, see if anyone can spot the bugs...
iZ!
I played with your library for a bit, the hexadecimal printout of Pi seem to be right
QuotePi
(0) 0000000000000003
(-1) 243F6A8885A308D3
...
but Pi/4 seems off
QuotePi/4
(0) 0000000000000001
(-1) C90FDAA22168C235
...
why is there a 1 in (0) element?
also, setting eps = New Hyper("1e-1000") doesn't work right, had to use eps = New Hyper("1e-1018")
but when setting eps = New Hyper("1e-2018") the Pi program only gives 718 correct digits
I think that you need to fix/fine tune your conversion routines, also you need to implement MP division, currently you only have division by Integer
Quote from: jack on September 16, 2024, 10:53:00 PMiZ!
I played with your library for a bit, the hexadecimal printout of Pi seem to be right
QuotePi
(0) 0000000000000003
(-1) 243F6A8885A308D3
...
it prints out pi correctly in decimal too
Quote from: jack on September 16, 2024, 10:53:00 PMwhy is there a 1 in (0) element?
Ha! :) because it is a balanced numeral system => 0.5 is represented as ...00001.100000... every top bit in QWORD is negative
Quote from: jack on September 16, 2024, 10:53:00 PMalso, setting eps = New Hyper("1e-1000") doesn't work right, had to use eps = New Hyper("1e-1018")
but when setting eps = New Hyper("1e-2018") the Pi program only gives 718 correct digits
I know these don't work for some reason... Please use
For i% = 0 To 90
eps.Divide(10 ^ 18, prec)
Next
orQuote from: i Z ! on September 15, 2024, 10:38:36 PMif you need only a small number for 'eps', you can do this by
Dim eps as New Hyper(-20,-20)
eps(-20) = 1
and set the (20*64)th bit after the decimal point. This way, the buffer size is only 1 QWORD
if the value doesn't need to be a divisor of 10.
Quote from: jack on September 16, 2024, 10:53:00 PMto implement MP division, currently you only have division by Integer
For now, I'm leaving this to the user to help himself with the
QuickDivide (https://masm32.com/board/index.php?msg=133222) procedure :) but yeah, you're right, I'll have to look into it, to optimally adjust the precision
Quote from: i Z ! on September 16, 2024, 11:35:55 PMHa! :) because it is a balanced numeral system => 0.5 is represented as ...00001.100000... every top bit in QWORD is negative
is there any advantage to using this "balanced numeral system" ?
the output is confusing, the hex value of Pi is exactly the same as Pi in base 16, same with Pi/4 except that you have a 1 in (0)
I did some timing comparison of HyperLib vs my binary floating point package using my little Pi program with eps=1e-1018
I compiled your Hyper version to x64 release and it didn't fare well against mine
but seriously, good input and output is essential, entering numbers using Hyper(-20,-20) is only acceptable to you the developer
Quote from: jack on September 17, 2024, 12:52:07 AMis there any advantage to using this "balanced numeral system" ?
Yes. No rounding error + no need of filling bits when expanding mantissa's size
Quote from: jack on September 17, 2024, 12:52:07 AMI did some timing comparison of HyperLib vs my binary floating point package using my little Pi program with eps=1e-1018
I compiled your Hyper version to x64 release and it didn't fare well against mine
I'm almost sure that by playing with precision (now it's 50*64 bits), you could pimp it to perform faster than yours
just make sure you're using the same value for eps in both tests. And, I would measure time only for the computational part, skipping the time taken for assigning the variables
to be fair, my binary FP is written in FreeBasic using the gcc backend, it would be too painful to rewrite in VB.Net
one problem with your HyperLib is that precision control is not accurate, after some trial and error I found that if Precision = 9000, eps = "10018" then Pi is calculated to 10005 correct digits
FB has reliable and easy constructor/destructor mechanisms whereas I found it impossible for VB.Net to invoke the destructor or Finalize, I finally gave up in disgust
I don't care to pursue this topic any further, good luck
Quote from: jack on September 17, 2024, 03:22:17 AMit would be too painful to rewrite in VB.Net
why'd you want to do that anyway?
Quote from: jack on September 17, 2024, 03:22:17 AMone problem with your HyperLib is that precision control is not accurate, after some trial and error I found that if Precision = 9000, eps = "10018" then Pi is calculated to 10005 correct digits
Please explain further, what do you mean "precision control is not accurate"? Precision in hyperlib is expressed as negated lowest exponent (which is 2^64 based, not 10)
Quote from: jack on September 17, 2024, 03:22:17 AMFB has reliable and easy constructor/destructor mechanisms whereas I found it impossible for VB.Net to invoke the destructor or Finalize, I finally gave up in disgust
I'm not sure, but maybe you're looking for something like "x = Nothing" and then, if needed, "GC.Collect" ?
VB.Net modules should test in many CPUs, as it isn't native code and sometimes locally optimized in target system.
Q1: to make a fair comparison on the performance of your Hyper vs my FP, but it's not practical to convert to VB.Net
Q2: I think it's stated clearly enough
Q3: I placed a Console.WriteLine("Finalize()") in Sub Finalize() to see whether it would get called but it never does
when a variable created by Sub New() that allocates memory goes out of scope it needs to de-allocate said memory but finalize never gets called
Quote from: jack on September 18, 2024, 02:23:09 AMwhen a variable created by Sub New() that allocates memory goes out of scope it needs to de-allocate said memory but finalize never gets called
you got me there, Sub Finalize is my weak spot, I never use/implement it... but don't you think "x = Nothing" and "GC.Collect" would do the job? You could also unassign the buffer by "x = New Hyper(0,0)"
Also, it is possible to have an external array as buffer
Dim ar&(30)
Dim h as New Hyper(ar) 'or maybe an extra argument for the exponent
and then you can dispose of that array which ever way you want
@jack, I haven't tried, but I guess you could reference hyperlib from outside of VS environment. The dll is located in "Program Files\iZ!"
Version 2.2.0 (https://marketplace.visualstudio.com/items?itemName=SilverfoxSystems0.Hyper)
- Conversion from decimal with a negative exponent fixed (e.g. "1e-1000")
- Corrected Add(Int64, Exp) procedure, which was maybe causing to occasionaly misinterpret decimal output
Also I've put back up my website again with References page (http://izi.wtf/Hyper/Descriptions/references.aspx) (website moved to izi.wtf)
if anyone cares to test... but it's still not code-signed so prepare for all kinds of warnings before installation
Fast conversion to Double added in v2.3
a = New Hyper("-.353e50")
Dim d#
a.ExtractDouble(d)
hey all,
new version should work much faster
- optimized multiplication by another Hyper; it was calling the below mentioned routine before each Add operation
- removed unnecessary buffer-resizing statements called in a procedure prior to actual Add and Subtract operations
- slightly optimized Add and Subtract procedures themselves
- added option to skip boundary check altogether, e.g. hyp1.Add(hyp2, False)
At some point, I changed tactics - the +/- procedures now don't check the buffer's upper bound, it just flows until there's a remainder. But with new tactics came new mistakes :)
EDIT: In theory, it sounds nice, but after testing on the same day, I found that nothing is faster... Only way I can explain this is that ReDim(LBnd, UBnd) takes no time to execute
my division function had an error,
If (lowVal And 1) = 0 Then
instead of If lowVal And 1 = 0 Then
https://masm32.com/board/index.php?msg=133222
here's a little cleaner code, with no output messages:
Private Function QuickDivide(dividend As Hyper, d As Hyper) As Hyper
Return dividend * ReciprocalVal(d)
End Function
Private Function ReciprocalVal(d As Hyper) As Hyper
precision% = 18 'number of 64-bit digits to extract. Must be larger than exponent range
precision2% = 180 'may be zero
Dim r As New Hyper(precision, 0) ' New Hyper(0, 0)
Dim bp, r1 As Hyper
hiExp% = d.FindHighExponent
lowExp% = d.FindLowExponent '000000000000000000000000000000000000000000000 d.PartSize
lowVal& = d(lowExp)
Dim mq&
If (lowVal And 1) = 0 Then
' Debug.WriteLine("even nr")
'if the least significant bit is 0, then we can help ourselves with dividing/multiplying the dividend, and then the result, by 2^n.
' d(lowExp) = d(lowExp) Or 1
'lowVal& = d(lowExp)
d(lowExp - 1) = 1
lowVal = 1
lowExp -= 1
mq = -1
Else
mq& = GetMagicNr(lowVal)
End If
d.PartSize = 0
bp = New Hyper("1")
pos1% = 0
mainloop:
' get the sequence which, when multiplied by divisor, nullifies itself
r1 = New Hyper(pos1, pos1)
r1(pos1) = bp(pos1) * mq
r(pos1) = r1(pos1)
bp -= d * r1
bp.Negate()
pos1 += 1
If pos1 > precision Then GoTo nx
'reciprocal values of large numbers tend to repeat at very large intervals, so we'll be satisfied with our precision
GoTo mainloop
nx:
r1 = r * d
hi% = r1.FindHighExponent
r.Divide(r1(hi), precision2)
r.PartSize = hi + r1.PartSize + r.PartSize + lowExp '.PartSize
d.PartSize = -lowExp
Return r
End Function
Private Function GetMagicNr&(a&)
' Magic number or "reciprocal integer" - GET THE 64-BIT NUMBER WHICH, when multiplied by the lowest digit, gives 1 as the remainder of 2^64
' Only for odd numbers.
bt& = 1 'bit tester
d& = a 'bit mask
r& = 0 : i& = 0 : r0& = 0
For i = 0 To 63
If bt And r Then GoTo skip
r += d
r0 = r0 Or bt
skip:
bt <<= 1 : d <<= 1
Next
Return r0
End Function