Integer Maths vs floating point - page 2 - Script Writing - CHDK Forum

Integer Maths vs floating point

  • 40 Replies
  • 7645 Views
Re: Integer Maths vs floating point
« Reply #10 on: 26 / April / 2021, 01:38:05 »
Advertisements
@philmoz

One problem I found was that using the imath approach meant I was increasing the size of the number by 1000, thus I found I was breaching the max size in the calculation.

My ‘solution’ when doing my DoF calculations was to not use imath, ie just integer calculations where I broke down the calculation into the sum of smaller calculations.  This way each smaller calculation would only contribute a mm max ‘error’, hardly an issue for non macro stuff.

For example, imul’s limits are:

-2147352'576 <= x, a, b, c <= 2147352'576

Some of the DoFs have terms like p*h*h, where p is the pupil mag and h is the hyperfocal.
« Last Edit: 26 / April / 2021, 01:51:30 by pigeonhill »

*

Offline philmoz

  • *****
  • 3450
    • Photos
Re: Integer Maths vs floating point
« Reply #11 on: 26 / April / 2021, 01:48:48 »
A floating point version of imathlib would have no scaling - all the values would be store as single precision floats and the calculations would be done using single precision float operations.


Obviously there would need to be conversion functions to get the integer or decimal part of the float value.

CHDK ports:
  sx30is (1.00c, 1.00h, 1.00l, 1.00n & 1.00p)
  g12 (1.00c, 1.00e, 1.00f & 1.00g)
  sx130is (1.01d & 1.01f)
  ixus310hs (1.00a & 1.01a)
  sx40hs (1.00d, 1.00g & 1.00i)
  g1x (1.00e, 1.00f & 1.00g)
  g5x (1.00c, 1.01a, 1.01b)
  g7x2 (1.01a, 1.01b, 1.10b)

Re: Integer Maths vs floating point
« Reply #12 on: 26 / April / 2021, 02:01:40 »
@philmoz

What would be the limits then for a multiply. Using the imath approach you have the limit that the result needs to be scaled down. Are you saying your idea would mean results could be much larger?

The worst limit is the sqrt

If someone is prepared to implement such a feature, I would be more than happy to tests it out in my scripts.

BTW I attach two versions of the far DoF expression, as measured from the front principal. As you can see, according to what version you use, you can have terms that are large, ie for far distances (u), and/or large focal lengths, ie large hyperfocals, and pupil mags.
« Last Edit: 26 / April / 2021, 02:42:51 by pigeonhill »

*

Offline philmoz

  • *****
  • 3450
    • Photos
Re: Integer Maths vs floating point
« Reply #13 on: 26 / April / 2021, 06:16:36 »
@pigeonhill


i took a look and this seems to be feasible. It will take me a little while to implement.


What camera / firmware version would you want to test on?


Note: some things would work a bit differently from imathlib. For example you could not add or subtract two values directly like you can with imathlib. You would need to use a function for this like what is used for multiplication and division.


Phil.

CHDK ports:
  sx30is (1.00c, 1.00h, 1.00l, 1.00n & 1.00p)
  g12 (1.00c, 1.00e, 1.00f & 1.00g)
  sx130is (1.01d & 1.01f)
  ixus310hs (1.00a & 1.01a)
  sx40hs (1.00d, 1.00g & 1.00i)
  g1x (1.00e, 1.00f & 1.00g)
  g5x (1.00c, 1.01a, 1.01b)
  g7x2 (1.01a, 1.01b, 1.10b)


Re: Integer Maths vs floating point
« Reply #14 on: 26 / April / 2021, 06:21:12 »
@philmoz

That's great news and I really appreciate your help.

I would welcome this on an M3  120f build.

Is there any read ahead I can look at regarding functionality etc.

Cheers

Garry

*

Offline philmoz

  • *****
  • 3450
    • Photos
Re: Integer Maths vs floating point
« Reply #15 on: 26 / April / 2021, 07:14:41 »
@pigeonhill


Do you need the trigonometry functions in imathlib?


The others are fairly easy; but the trig functions will be more work.


Usage would be similar to the imath functions, e.g.
  fmath.mul(a,b), fmath.div(a,b), fmath.sqrt(x), fmath.log(x), etc


Initialisation of an fmath variable is a bit different:
  x = fmath.fromInt(45,10)   creates a float with value 4.5 (45 / 10)


To get the whole and fractional parts as integer values:
  i, f = fmath.toInt(val, scale)
Sets 'i' to the whole number part of the 'val' float and 'f' to the fractional part multiplied by scale.
If x = 4.5 then fmath.toInt(x,1000) would return values of 4 and 500.


String conversion - fmath.toStr(val, format). E.G. fmath.toStr(val, "%.3f") would return a string version of the float value to 3 decimal places.


So long as you only use the fmath functions to operate on the float values it should all work - Lua will allow you to perform integer operations on the values since they are stored as 32 bit integer values; but the results will be incorrect.

CHDK ports:
  sx30is (1.00c, 1.00h, 1.00l, 1.00n & 1.00p)
  g12 (1.00c, 1.00e, 1.00f & 1.00g)
  sx130is (1.01d & 1.01f)
  ixus310hs (1.00a & 1.01a)
  sx40hs (1.00d, 1.00g & 1.00i)
  g1x (1.00e, 1.00f & 1.00g)
  g5x (1.00c, 1.01a, 1.01b)
  g7x2 (1.01a, 1.01b, 1.10b)

Re: Integer Maths vs floating point
« Reply #16 on: 26 / April / 2021, 08:01:29 »
@philmoz

Quote
Do you need the trigonometry functions in imathlib?

My priority would be mul. div, sqrt, log etc.

I do use trig functions, but these are not a priority.

Plus, I assume, as long as I don't mix things up, I can carry on using an imath library call if required.

Bottom line: priority is the non-trig maths stuff ;-)

Cheers

Garry

*

Offline reyalp

  • ******
  • 14080
Re: Integer Maths vs floating point
« Reply #17 on: 26 / April / 2021, 13:36:23 »
So long as you only use the fmath functions to operate on the float values it should all work - Lua will allow you to perform integer operations on the values since they are stored as 32 bit integer values; but the results will be incorrect.
I would suggest implementing it with userdata, since there is few if any circumstance where treating it as a number would work well (possibly you could sneak it through to printf / string.format functions with %f and get the right thing). I doubt it would be much more work, and it would allow you to use doubles and give the normal arithmetic operators their usual meanings, if you want.
Don't forget what the H stands for.


*

Offline philmoz

  • *****
  • 3450
    • Photos
Re: Integer Maths vs floating point
« Reply #18 on: 26 / April / 2021, 23:15:21 »
Thanks @reyalp - userdata makes much more sense.

@pigeonhill - attached is a build for the M3 1.20f.

I've also attached a patch of the code changes (includes a test script).
I'm not a Lua expert so this could probably be improved in many ways; but it seems to work.

The usage is a bit different to what I posted earlier:

Create a new fmath double variable:
  x = fmath.new(n,d)
Set x to n / d.
E.G.
  x = fmath.new(45,10)     sets x = 4.5
  y = fmath.new(25,100)   sets y = 0.25
Parameter d is optional and defaults to 1 - x = fmath.new(5) is equivalent to x = fmath.new(5,1)

Arithmetic - use standard operators.
E.G.
  z = x + y
  z = x - y
  z = x * y
  z = x / y
  z = -x
  z = x ^ y   (power function)
So long as either parameter is an fmath double the result will be an fmath double. The following are both valid:
  z = x + 1
  z = 1 + x

Comparison - as above use standard operators ==, ~=, <, <=, >, >=

Math functions:
  log, log2, log10, sqrt
Can be called via fmath library or object oriented syntax. The following are equivalent:
  y = fmath.log(x)   ==>     y = x:log()
  y = fmath.sqrt(x)   ==>     y = x:sqrt();

Conversion:
  int, ceil, floor, round, deg, rad
These can also be called via the fmath library or object oriented syntax as above.
The int, ceil, floor and round functions return integer values not fmath doubles.
The deg and rad functions convert between degrees and radians and return an fmath double value.

There is also a function to convert to a string:
  fmath.tostr(x, format) or x:tostr(format).
This returns a string of the double value using the supplied format string. The format parameter is optional and defaults to "%f".

The frac function from imathlib is not implemented. The imathlib function is mathematically wrong for negative values.
You can get the equivalent of the imathlib frac function using:
  f = (x - x:int()) * 1000
The correct value would be:
  f = (x - x:floor()) * 1000


Edit: attachments updated to include comparison operators and unary minus operator.

« Last Edit: 27 / April / 2021, 00:07:14 by philmoz »
CHDK ports:
  sx30is (1.00c, 1.00h, 1.00l, 1.00n & 1.00p)
  g12 (1.00c, 1.00e, 1.00f & 1.00g)
  sx130is (1.01d & 1.01f)
  ixus310hs (1.00a & 1.01a)
  sx40hs (1.00d, 1.00g & 1.00i)
  g1x (1.00e, 1.00f & 1.00g)
  g5x (1.00c, 1.01a, 1.01b)
  g7x2 (1.01a, 1.01b, 1.10b)

Re: Integer Maths vs floating point
« Reply #19 on: 27 / April / 2021, 01:31:58 »
@philmoz

I’m amazed how quickly this has been done. Many thanks.

As soon as I can I’ll give you feedback.

Once again, many thanks for implementing this.

Cheers

Garry

 

Related Topics