Why the remainder of a float divided by a bigger integer than itself returns the float itself? - ruby

I'm pretty new to programming concept totally I am learning ruby at the moment!
I was playing a bit around with irb and saw the remainder of a floating point divided by an integer bigger than itself return the float itself.
for example 2.5 % 5 returned 2.5.
I was expecting the result of the above equation to be 0 since if we divide 2.5 by 5 the answer will be 0.5 and remainder 0.
Can you help me understand why this is the behavior or am I mathematically wrong?
Thanks in advance

You are mathematically wrong: 2.5 divided by 5 is not 5. It is 0.5. Or, if you are talking about "integer division" (i.e. division where the result is always an integer), the result is 0. 0 * 2.5 is 0, therefore, the remainder is 2.5.
Actually, this is true for any pair of numbers a and b where b > a that a % b == a.

The doc for Numeric#% states: "x.modulo(y) means x-y*(x/y).floor". In your example that means:
2.5 % 5
#=> 2.5 - 5*(2.5/5).floor
#=> 2.5 - 5*(0.5.floor) => 2.5 - 5 * 0 => 0.5
Consider four more examples.
9 % 2.0
#=> 9 - 2.0*(9/2.0).floor
#=> 9 - 2.0*(4.5.floor) => 9 - 2.0*4 => 1.0
9.0 % 2
#=> 9.0 - 2*(9.0/2).floor
#=> 9.0 - 2*(4.5.floor) => 9.0 - 2.0*4 => 1.0
9.0 % 2.0
#=> 9.0 - 2.0*(9.0/2.0).floor
#=> 9.0 - 2.0*(4.5.floor) => 9.0 - 2.0*4 => 1.0
9 % 2
#=> 9 - 2*(9/2).floor
#=> 9 - 2*(4.floor) => 9 - 2*4 => 1
The doc for Float#% (aka Float#modulo) gives two more examples:
6543.21 % 137
#=> 6543.21 - 137*((6543.21/137).floor)
#=> 6543.21 - 137*(47.76065693430657.floor)
#=> 6543.21 - 137*47
#=> 104.21000000000004
6543.21 % 137.24
#=> 6543.21 - 137.24*((6543.21/137.24).floor)
#=> 6543.21 - 137.24*(47.67713494607986.floor)
#=> 6543.21 - 137.24*47
#=> 92.92999999999961

% - is modulo operator
(In computing, the modulo operation finds the remainder after division of one number by another (called the modulus of the operation)
In your case, this is correct:
2.5 % 5 = 2.5
/ - is division
2.5 / 5 = 0.5
As soon as you include one number as float, in this case 2.5, Ruby will automatically convert the result to float even if another number is a string.
I hope this helps,
Augustas

Related

Find all natural numbers which are multiplies of 3 and 5 recursively

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000.
def multiples_of(number)
number = number.to_f - 1.0
result = 0
if (number / 5.0) == 1 || (number / 3.0) == 1
return result = result + 5.0 + 3.0
elsif (number % 3).zero? || (number % 5).zero?
result += number
multiples_of(number-1)
else
multiples_of(number-1)
end
return result
end
p multiples_of(10.0)
My code is returning 9.0 rather than 23.0.
Using Core Methods to Select & Sum from a Range
It's not entirely clear what you really want to do here. This is clearly a homework assignment, so it's probably intended to get you to think in a certain way about whatever the lesson is. If that's the case, refer to your lesson plan or ask your instructor.
That said, if you restrict the set of possible input values to integers and use iteration rather than recursion, you can trivially solve for this using Array#select on an exclusive Range, and then calling Array#sum on the intermediate result. For example:
(1...10).select { |i| i.modulo(3).zero? || i.modulo(5).zero? }.sum
#=> 23
(1...1_000).select { |i| i.modulo(3).zero? || i.modulo(5).zero? }.sum
#=> 233168
Leave off the #sum if you want to see all the selected values. In addition, you can create your own custom validator by comparing your logic to an expected result. For example:
def valid_result? range_end, checksum
(1 ... range_end).select do |i|
i.modulo(3).zero? || i.modulo(5).zero?
end.sum.eql? checksum
end
valid_result? 10, 9
#=> false
valid_result? 10, 23
#=> true
valid_result? 1_000, 233_168
#=> true
There are a number of issues with your code. Most importantly, you're making recursive calls but you aren't combining their results in any way.
Let's step through what happens with an input of 10.
You assign number = number.to_f - 1.0 which will equal 9.
Then you reach the elsif (number % 3).zero? || (number % 5).zero? condition which is true, so you call result += number and multiples_of(number-1).
However, you're discarding the return value of the recursive call and call return result no matter what. So, your recursion doesn't have any impact on the return value. And for any input besides 3 or 5 you will always return input-1 as the return value. That's why you're getting 9.
Here's an implementation which works, for comparison:
def multiples_of(number)
number -= 1
return 0 if number.zero?
if number % 5 == 0 || number % 3 == 0
number + multiples_of(number)
else
multiples_of(number)
end
end
puts multiples_of(10)
# => 23
Note that I'm calling multiples_of(number) instead of multiples_of(number - 1) because you're already decrementing the input on the function's first line. You don't need to decrement twice - that would cause you to only process every other number e.g. 9,7,5,3
explanation
to step throgh the recursion a bit to help you understand it. Let's say we have an input of 4.
We first decrement the input so number=3. Then we hits the if number % 5 == 0 || number % 3 == 0 condition so we return number + multiples_of(number).
What does multiples_of(number) return? Now we have to evaluate the next recursive call. We decrement the number so now we have number=2. We hit the else block so now we'll return multiples_of(number).
We do the same thing with the next recursive call, with number=1. This multiples_of(1). We decrement the input so now we have number=0. This matches our base case so finally we're done with recursive calls and can work up the stack to figure out what our actual return value is.
For an input of 6 it would look like so:
multiples_of(6)
\
5 + multiples_of(5)
\
multiples_of(4)
\
3 + multiples_of(3)
\
multiples_of(2)
\
multiples_of(1)
\
multiples_of(0)
\
0
The desired result can be obtained from a closed-form expression. That is, no iteration is required.
Suppose we are given a positive integer n and wish to compute the sum of all positive numbers that are multiples of 3 that do not exceed n.
1*3 + 2*3 +...+ m*3 = 3*(1 + 2 +...+ m)
where
m = n/3
1 + 2 +...+ m is the sum of an algorithmic expression, given by:
m*(1+m)/2
We therefore can write:
def tot(x,n)
m = n/x
x*m*(1+m)/2
end
For example,
tot(3,9) #=> 18 (1*3 + 2*3 + 3*3)
tot(3,11) #=> 18
tot(3,12) #=> 30 (18 + 4*3)
tot(3,17) #=> 45 (30 + 5*3)
tot(5,9) #=> 5 (1*5)
tot(5,10) #=> 15 (5 + 2*5)
tot(5,14) #=> 15
tot(5,15) #=> 30 (15 + 3*5)
The sum of numbers no larger than n that are multiple of 3's and 5's is therefore given by the following:
def sum_of_multiples(n)
tot(3,n) + tot(5,n) - tot(15,n)
end
- tot(15,n) is needed because the first two terms double-count numbers that are multiples of 15.
sum_of_multiples(9) #=> 23 (3 + 6 + 9 + 5)
sum_of_multiples(10) #=> 33 (23 + 2*5)
sum_of_multiples(11) #=> 33
sum_of_multiples(12) #=> 45 (33 + 4*3)
sum_of_multiples(14) #=> 45
sum_of_multiples(15) #=> 60 (45 + 3*5)
sum_of_multiples(29) #=> 195
sum_of_multiples(30) #=> 225
sum_of_multiples(1_000) #=> 234168
sum_of_multiples(10_000) #=> 23341668
sum_of_multiples(100_000) #=> 2333416668
sum_of_multiples(1_000_000) #=> 233334166668

Convert number to their log2

I need to convert number into their minimal log2 +1, but I have a problem, that in 32-bit Ruby, log2(8) = 2.9999999999999996
The input (pos) and output (level) should be:
1 -> 1
2-3 -> 2
4-7 -> 3
8-15 -> 4
16-31 -> 5
and so on..
My formula:
pos = 8
level = ( Math.log(pos,2) + 1 ).to_i
# 3 (wrong) in 32-bit Ruby
# 4 (correct) in 64-bit Ruby
Is there more way to prevent this from happening or is there any other formula that convert pos to correct level as shown above?
pos = 8
level = 0
until pos < 2
level += 1
pos /= 2
end
level + 1 #=> 4
Here's another interesting way to compute the floored logarithm for integers:
0.upto(Float::INFINITY).find{|e| x - base**e < base }
The maximum representable value with IEEE 754-2008 binary32 is (2−2**(−23)) × 2**127, so the base 2 log of a number stored in binary 32 is less than decimal 128. Since the round-off error is a small fraction of one, we can round to the nearest integer and see if 2 to that integer power equals the given number. If it does, return the integer power; else return nil, signifying that it is not a power of 2.
def log_2_if_integer(n)
x = Math.log(n,2).round(0).to_i
(2**x == n) ? x : nil
end
log_2_if_integer(4) #=> 2
log_2_if_integer(512) #=> 9
log_2_if_integer(3) #=> nil
In other words, because the log is less than 128, rounding error could not produce a value x such that 2**(x+m) == n for any (positive or negative) integer m != 0.

In Ruby how do you round down a number to 2 significant digits

For example,
If I have 24987654, I need it to return 24000000, is this possible?
Here is one naive algorithm :
n = 24987654
n / (10 ** (n.to_s.size - 2)) * (10 ** (n.to_s.size - 2)
=> 24000000
Here's another way to do it:
x -= x % (10 ** (Math.log(x, 10).to_i - 1))
In the above statement:
Math.log(x, 10).to_i - 1 determines the number of insignificant digits to remove
x % (10 ** number_of_insignificant_digits) computes the insignificant part of the number
subtract the value from step 2 from the initial number and now x contains the result
Here's an online test for the program: http://ideone.com/trSNOr
n = 24987654
n.round((n.to_s.size - 2)*-1) #=> 25000000
n.ceil((n.to_s.size - 2)*-1) #=> 25000000
n.floor((n.to_s.size - 2)*-1) #=> 24000000
n = 24187654
n.round((n.to_s.size - 2)*-1) #=> 24000000
n.ceil((n.to_s.size - 2)*-1) #=> 25000000
n.floor((n.to_s.size - 2)*-1) #=> 24000000
Just another way:
n = 24987654
a = n.to_s[0, 2] + '0' * ((a.to_s.length)-2)
Will output the string:
=> "24000000"
You can convert it as integer calling the .to_i method

Why is `27 ** (1.0/3.0)` different from `27 ** (1/3)`?

Please let me know if this is correct way to get the cubic root.
I can't understand why
27 ** (1.0/3.0) #=> 3
is different from
27 ** (1/3) #=> 1
1.0 / 3.0 # => 0.3333333333333333
27 ** 0.333 # => 2.9967059728946346
1 / 3 # => 0
27 ** 0 # => 1
The second is an example of integer division. How many threes are there in one? Zero. Any number in power 0 is 1.
The first division is a decimal division and the latter is an integer division
that is 1.0/3.0 will yield a decimal result whereas 1/3will yield an integer result which in this case i 0
the results will therefor be different since it's the result of either
27**0.333...
or
27**0
which of course are clearly different.
It's enough to force one of the operators to be decimal for the entire operation to yield a decimal result e.g. 1/3.0 will yield 0.3333...
Integer division results in integers:
irb(main):004:0> 1/3
=> 0
irb(main):005:0> 1.0/3.0
=> 0.3333333333333333
27**0 = 1. 27**(1/3) = 3
(1/3) returns 0 since 3 is an integer. in ruby, if you divide using integers for both the divisor and dividend, you going to get an integer value. and since anything raised to 0 is 1, your get 1 as the answer
(1.0/3.0) returns 0.3333 since you're not dividing 2 integers so you get 3 from 27 ** 0.33...
Type conversation.
When you compute 1.0/3.0 - It is decimal
Which is 1.0/3.0 = 0.33 # which is a decimal
1/3 - It rounds to the nearest integer.
Thus:
27 ** (1.0/3.0) #=> 3
is different from
27 ** (1/3) #=> 1

How to find remainder of a division in Ruby?

I'm trying to get the remainder of a division using Ruby.
Let's say we're trying to divide 208 by 11.
The final should be "18 with a remainder of 10"...what I ultimately need is that 10.
Here's what I've got so far, but it chokes in this use case (saying the remainder is 0).
division = 208.to_f / 11
rounded = (division*10).ceil/10.0
remainder = rounded.round(1).to_s.last.to_i
The modulo operator:
> 208 % 11
=> 10
If you need just the integer portion, use integers with the / operator, or the Numeric#div method:
quotient = 208 / 11
#=> 18
quotient = 208.0.div 11
#=> 18
If you need just the remainder, use the % operator or the Numeric#modulo method:
modulus = 208 % 11
#=> 10
modulus = 208.0.modulo 11
#=> 10.0
If you need both, use the Numeric#divmod method. This even works if either the receiver or argument is a float:
quotient, modulus = 208.divmod(11)
#=> [18, 10]
208.0.divmod(11)
#=> [18, 10.0]
208.divmod(11.0)
#=> [18, 10.0]
Also of interest is the Numeric#remainder method. The differences between all of these can be seen in the documentation for divmod.
please use Numeric#remainder because mod is not remainder
Modulo:
5.modulo(3)
#=> 2
5.modulo(-3)
#=> -1
Remainder:
5.remainder(3)
#=> 2
5.remainder(-3)
#=> 2
here is the link discussing the problem
https://rob.conery.io/2018/08/21/mod-and-remainder-are-not-the-same/

Resources