Page 1 of 1

Multiplication Overflow

Posted: 21 Apr 2020 23:54
by choibakk
I'm trying to implement a version of "De Bruijn Multiplication" that counts on an arithmetic overflow. For instance: multiplying let say V=512, so (V * 0x03f79d71b4cb0a89). I have everything working except for the overflow. And I checked the correct functionality using a programming calculator to ensure my concept of the algorithm is correct. I've tried using the "/NOCheck" compile option to no success. The documentation seemed a little vague to my understanding on where exactly where to use #options "/NOCheck", so I tried various places (the documentations mentions: "In the file sent to the compiler".. I also added "/NOCheck" as a global compiler option for the whole project using the IDE -> Project -> Settings -> "Additional Compiler Options".

So I think I'm either doing something wrong, or don't properly understand how to turn off the overflow check. Ideally, I would like to limit the scope of turning off the overflow check for a single line of code. Any suggestions?

I was hoping not to write an external function in something like C++ or Assembly for the first version of my program, but can resort to that if needed. Thanks!

Edit: I'm using VP9 Rev 902, the project is 64-bit, and my variables are "unsigned64".

P.S. Visual Prolog is awesome!

Re: Multiplication Overflow

Posted: 22 Apr 2020 9:18
by Thomas Linder Puls
Visual Prolog arithmetic operators always checks overflow. The /nocheck option will disable other kinds of checks, but it will not change the behavior of the arithmetic operators.

I am afraid that implementing external functions is your only option. It should be possible to implement such simple functions without relying on any libraries and therefore I don't think you need to create a DLL, I think you can just compile a single file into an OBJ file and link that into the project. I am not sure if our project files accept OBJ files, but alternatively you can create a LIB file they should be treated correctly. Remember to use stdcall:

Code: Select all

class predicates     mult_noCheck : (unsigned64 A unsigned64 B) -> unsigned64 R language apicall.
And then I wrote apicall :-).

But apicall is stdcall which does not require an "external resolution".

Code: Select all

class predicates     mult_noCheck : (unsigned64 A unsigned64 B) -> unsigned64 R language stdcall. resolve     mult_noCehck externally
Also notice that the first letter must be lowercase in Visual Prolog, but uppercase in the external file.

Re: Multiplication Overflow

Posted: 23 Apr 2020 1:32
by choibakk
Thank you Thomas for the helpful response. I have implemented the external function in a DLL. I started with a lib as you suggested, and almost had it working but received a read IO error from the compiler on the static ".lib" file, so switched it to a DLL and it worked the very first time.

There is a strange issue with the IDE (haven't tested command-line compiler), where it adds a *extra* "64" to the directory name where it is looking for the ".lib". For example if I add a directory name to the "lib" section to the $(LibDir) setting in the project settings and place by library file in a "lib64" directory, it properly adds the "64" to the "lib" to produce "lib64", however, at compile time it adds an extra "64" to the directory where it is looking for the "lib" specified in the project. So as a workaround, I added an another directory "lib6464" and place a copy of the "lib" in that directory. A simple issue to workaround.

Now, I'm really happy I went through this process to call external functions. I'm really excited about having a supplement library for static functions that need pure raw speed without the need for pure logic programming.

Great job PDC! :D

Re: Multiplication Overflow

Posted: 23 Apr 2020 9:39
by Thomas Linder Puls
Actually, you should just add the LIB to the project tree by clicking "Add ..." in the context menu on the project tree.

However there is (as you noticed) a "glitch" in making a project (solely) for 64 bit. Our system is built to assume that you add 32 bit lib to the project and will then look for the corresponding 64 bit library in a parallel xxx64 folder.

We always follow this convention even if the project is only for one platform. That makes it easier should you decide to change platform, and it also makes it easier to handle system libraries (which are placed like that).

You will for example notice that your project contains $(ProDir)Lib\vipKernel.lib, but in reality your 64 bit project links with $(ProDir)Lib64\vipKernel.lib.

If you look in the project file (in text mode) you will also notice that that lib is just mentioned as a project member
<item-set key="filename">
<item-map filename="$(ProDir)Lib\vipInit.lib" />
<item-map filename="$(ProDir)Lib\vipKernel.lib" />
So the simplest way to deal with this is to add a dummy lib in a non-64 folder and then place real lib in the corresponding 64 folder. (I think that is also what you have done, however your non-64 folder happens to end in 64, and you 64 folder therefore ends in 6464).

Re: Multiplication Overflow

Posted: 23 Apr 2020 21:18
by choibakk
That makes perfect sense! Thanks.