# Problem with Mod() Funktion

## Recommended Posts

got problems on the funktion Mod() i got alltimes wrong output from this

mod("175367809538821201","1767842701") returns 421042353

but its wrong !?!

real output must be 421042338

why he tel me 421042353 and not 421042338 ?

what its wrong on this script ??

thx for help

##### Share on other sites

its ok i use a other way to got the right result

```func Mod2(\$a, \$b)
\$c = Int(\$a / \$b)
\$b = \$b * \$c
\$c = \$a - \$b
return \$c
EndFunc```

##### Share on other sites

This looks like a rounding problem. Mod is an integer function, but the numbers you gave are too big for integer (limited to just over 2 billion / 2 thousand-million). The fail-over is use floating-point numbers, but the storage for floating-point is limited and the least significant digits can be lost or scrambled during operations and storage, sort of like rounding off the decimals on a regular number.

Imagine that you are performing some calculations but you can only store 2 digits after the decimal point. This is an example of limited storage that I was talking about earlier.

Determine 500 / 17 * 17 = ?

500 / 17 = 29.41176470588235294118...

Rounding to the nearest 2 digits yields 29.41.

29.41 * 17 = 499.97

So under these circumstances, 500 / 17 * 17 = 499.97, due to rounding error.

The effect gets more noticeable with larger denominators and you are using a pretty big denominator.

The reason the second method, using int and subtraction, worked is that the Int function reset that precision back to 0 as it were. Much easier to work with.

One way to mitigate rounding errors is to see if you can simplify things before asking the computer to perform the calculations. The calculations can be faster and more accurate that way.

Edited by Nutster

David Nuttall
Nuttall Computer Consulting

An Aquarius born during the Age of Aquarius

AutoIt allows me to re-invent the wheel so much faster.

I'm off to write a wizard, a wonderful wizard of odd...

##### Share on other sites

got problems on the funktion Mod() i got alltimes wrong output from this

mod("175367809538821201","1767842701") returns 421042353

but its wrong !?!

real output must be 421042338

why he tel me 421042353 and not 421042338 ?

what its wrong on this script ??

thx for help

For the same reason that

mod(175367809538821201,175367809538821200)

gives 32 when you think it should be 1.

The internal precision of numbers is not great enough when dividing and multiplying.

This will work, and could be speeded up I expect

```\$a = 175367809538821201
\$b=1767842701
while \$a > \$b
\$a -= \$b
WEnd
ConsoleWrite(\$a & @CRLF);mod result```

EDIT:

The BigNum udf in example scripts does a much better job.

EDIT AGAIN: I didn't see post #2 until now. That's a much better idea

Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

##### Share on other sites

Try this:

```ConsoleWrite(15 / 175367809538821201 & @LF)

; Result = 8.55345119463298e-017```

The floating point format used hits rounding limits at about 15 significant digits. The difference in your answer is below that limit by two digits. You can reduce the introduced error by reducing the scale of the numbers below that limit, too:

```Global \$iX = 175367809538821201, \$iY = 1767842701

ConsoleWrite("Plain Mod():  " & Mod(\$iX, \$iY) & @LF) ; returns 421042353

ConsoleWrite("_MyMod():  " & _MyMod(\$iX, \$iY) & @LF) ; returns 421042338

Func _MyMod(\$A, \$B)
Local \$iScale

While \$B * 2 < \$A
\$iScale = \$B
While \$iScale * 2 < \$A
\$iScale *= 2
WEnd
\$A -= \$iScale
WEnd

Return Mod(\$A, \$B)
EndFunc   ;==>_MyMod```

Edit: Didn't see Martin's post while testing mine, but this should be faster at reducing the scale.

Edit2: Hmm... I thought that Int() trick in Mod2() above would fail too because of the non-integer parts of the method. But it works just as well as using all integer maths until the last operation.

Edited by PsaltyDS

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

## Create an account

Register a new account

×

• Wiki

• Back

• Git