Reputation: 3544
Hey I have a case where I tried to run this on REPL:
(1 to 100).toList.reduce(_*_)
And it Returned me 0. I did not understand this behavior. If the Int has been overflowed it should have returned any negative or positive number. I got curious hence I tried this:
(1 to 100).toList.fold(1)(_*_)
It still returned me 0 Then I tried this:
(1 to 100).toList.fold(1)((a,b) => { println(s"dd::::$a:::$b"); a*b })
It returns me :
scala> res0.toList.fold(1)((a,b) => { println(s"dd::::$a:::$b"); a*b })
dd::::1:::1
dd::::1:::2
dd::::2:::3
dd::::6:::4
dd::::24:::5
dd::::120:::6
dd::::720:::7
dd::::5040:::8
dd::::40320:::9
dd::::362880:::10
dd::::3628800:::11
dd::::39916800:::12
dd::::479001600:::13
dd::::1932053504:::14
dd::::1278945280:::15
dd::::2004310016:::16
dd::::2004189184:::17
dd::::-288522240:::18
dd::::-898433024:::19
dd::::109641728:::20
dd::::-2102132736:::21
dd::::-1195114496:::22
dd::::-522715136:::23
dd::::862453760:::24
dd::::-775946240:::25
dd::::2076180480:::26
dd::::-1853882368:::27
dd::::1484783616:::28
dd::::-1375731712:::29
dd::::-1241513984:::30
dd::::1409286144:::31
dd::::738197504:::32
dd::::-2147483648:::33
dd::::-2147483648:::34
dd::::0:::35
dd::::0:::36
dd::::0:::37
dd::::0:::38
dd::::0:::39
dd::::0:::40
dd::::0:::41
dd::::0:::42
dd::::0:::43
dd::::0:::44
dd::::0:::45
dd::::0:::46
dd::::0:::47
dd::::0:::48
dd::::0:::49
dd::::0:::50
dd::::0:::51
dd::::0:::52
dd::::0:::53
dd::::0:::54
dd::::0:::55
dd::::0:::56
dd::::0:::57
dd::::0:::58
dd::::0:::59
dd::::0:::60
dd::::0:::61
dd::::0:::62
dd::::0:::63
dd::::0:::64
dd::::0:::65
dd::::0:::66
dd::::0:::67
dd::::0:::68
dd::::0:::69
dd::::0:::70
dd::::0:::71
dd::::0:::72
dd::::0:::73
dd::::0:::74
dd::::0:::75
dd::::0:::76
dd::::0:::77
dd::::0:::78
dd::::0:::79
dd::::0:::80
dd::::0:::81
dd::::0:::82
dd::::0:::83
dd::::0:::84
dd::::0:::85
dd::::0:::86
dd::::0:::87
dd::::0:::88
dd::::0:::89
dd::::0:::90
dd::::0:::91
dd::::0:::92
dd::::0:::93
dd::::0:::94
dd::::0:::95
dd::::0:::96
dd::::0:::97
dd::::0:::98
dd::::0:::99
dd::::0:::100
res5: Int = 0
I do not understand this behavior clearly. Could anyone please help !Thanks
Upvotes: 1
Views: 264
Reputation: 149538
I do not understand this behavior clearly
Generally, what you're experiencing is arithmetic overflow. If you want to pinpoint exactly why the 34th value returns 0, then doing the calculation by hand can help.
The result of the 33th product is -2147483648
, which is:
64bit hex: 0xFFFFFFFF80000000
32bit hex: 0x80000000
64bit binary: 1111111111111111111111111111111110000000000000000000000000000000
32bit binary: 10000000000000000000000000000000
We multiply it by 34, we get:
64bit hex: 0xFFFFFFEF00000000
32bit hex: 0x00000000
64bit binary: 1111111111111111111111111110111100000000000000000000000000000000
32bit binary: 00000000000000000000000000000000
Since Int
looks at the lower 32bit, you get 0
. Everything on from here will result in 0
since that's the accumulators value and you're doing multiplication.
Upvotes: 5
Reputation: 4256
In your output there is one line like: dd::::-2147483648:::34
, which produces 0
as output. Hence all subsequent multiplications result in 0
.
Reason being -2147483648
in minimum value of Int
(Int.MinValue
).
scala> Int.MinValue
res6: Int = -2147483648
If you try -2147483648 + -2147483648
in REPL, because of Int
overflow, output will be 0
. Now when you do -2147483648 * 34
it is equivalent to (-2147483648 + (-2147483648)) * 17
, hence output is 0
.
Upvotes: 3
Reputation: 957
Execute the following to understand what is going on:
val x = Int.MinValue
x - 1 // = Int.MaxValue-1
x + x // = 0
x + x + x // = Int.MinValue
When you subtract from Int.MinValue you start from the max value. If you subtract abs(MinValue) from MinValue (MinValue * 2) you will be doing abs(MinValue) steps left from MaxValue which will bring you to 0.
This behaviour leads you to a situation in which MinValue * even number = 0 and MinValue * odd number = MinValue
Both behaviours occurred on lines 33-34, and of course as soon as one of you results is 0, all of your other results will be 0 as well.
Upvotes: 3