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

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

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

`to_i` method with base value as parameter in ruby

Can anyone explain how base parameter works when calling to_i with the following examples?
'2'.to_i(2) #=> 0
'3'.to_i(2) #=> 0
'12'.to_i(2) #=> 1
'122'.to_i(2) #=> 1
'20'.to_i(2) #=> 0
'21'.to_i(2) #=> 0
I do not understand how it's actually working. Can anyone explain please?
It is the same reason that '54thousand'.to_i is 54: to_i reads until it finds end of string or an invalid digit.
In binary (base 2), the only valid digits are 0 and 1. Thus, because 2 is invalid, '122'.to_i(2) is identical to '1'.to_i(2). Also, '2'.to_i(2) is identical to ''.to_i(2), which is rather intuitively 0.
base, in other word Radix means the number of unique digits in a numeral system.
In Decimal, we have 0 to 9, 10 digits to represent numbers.
You are using 2 as parameter, that means Binary, so there're only 0 and 1 working.
From the Doc of to_i:
Returns the result of interpreting leading characters in str as an
integer base base (between 2 and 36). Extraneous characters past the
end of a valid number are ignored. If there is not a valid number at
the start of str, 0 is returned. This method never raises an
exception when base is valid.
You can use these number representations directly in Ruby:
num_hex = 0x100
#=> 256
num_bin = 0b100
#=> 4
num_oct = 0o100
#=> 64
num_dec = 0d100
#=> 100

Understanding this snippet 'D' * (num % 1000 / 500)

Can anyone explain how to read this code and what it will do?
'D' * (num % 1000 / 500)
It is from a method for converting integers to Roman numerals. I don't understand how it functions.
It is pretty obfuscated indeed. I guess the idea was to put one or zero Ds depending on if you get a number greater than 500 after you get the remainder of division by 1000.
The order of the operations:
num % 1000
num modulo 1000. Will leave the last three digits.
/ 500
Will see if the last three digits are greater than 500.
String#* repeats a string:
'x' * 5 # => "xxxxx"
The reason that is needed is because D is the letter for 500. You will have only one or zero of these as M is the letter for 1000.
The expression (num % 1000 / 500) means "if you have in your last 3 digits a number greater than 500 then evaluate to 1 otherwise evaluate to 0"
"D" * (0 or 1) is determining whether to put "D" on the roman number or not.
What it Does
The expression is a way of building the Roman numeral five-hundreds digit, which is 'D'.
It takes any number, extracts only the three rightmost digits (values 0 through 999), and returns a 'D' only if the value is 500 or greater. Otherwise it returns an empty string ''
How to Read it
In Ruby, the multiply *, divide /, and modulus % symbols have equal precedence and are processed in order from left to right. Parentheses, however, have a higher precedence than these three operators.
To help visualize the processing order, you can add optional parentheses:
'D' * ( ( num % 1000 ) / 500 )
num % 1000:
extracts the three rightmost digits of a number, resulting in values 0 - 999
{0-999} / 500:
determines if value is 500 or greater, or not.
Returns 1 if so, 0 if not.
In Ruby, integer division does not automatically convert to decimals.
'D' * {1 or 0}:
In Ruby, multiplying a string by 1 returns the string, multiplying by 0 returns an empty string
Examples
For a number 35,045:
35045 % 1000 #=> 45
45 / 500 #=> 0
'D' * 0 #=> ""
For a number 468,987:
468987 % 1000 #=> 987
987 / 500 #=> 1
'D' * 1 #=> "D"
For a number 670:
670 % 1000 #=> 670
670 / 500 #=> 1
'D' * 1 #=> "D"
For a number 7:
7 % 1000 #=> 7
7 / 500 #=> 0
'D' * 0 #=> ""
See this page and scroll down to Ruby Operators Precedence.
Multiplication, division, and modular arithmetic are all together, so precedence is left to right IIRC.
First, num % 1000 is evaluated. Then, that is divided by 500. That's then multiplied by 'D'.
The modulus % and division / operators have the same precedence.
So associativity, which is from left to right for these operators, comes into play.
Therefore the expression is equivalent to 'D' * ((num % 1000) / 500): you are multiplying 'D' by the last 3 digits of num divided by 500.

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.

Unexpected result from math expression

i am using ruby irb
-1/4
=> -1
0-1
=> -1
0-1/4
=> 0
How come it'll be zero for 0-1/4 ?
My calculation is as shown in below pic
1/4 is zero - since both operands are integers, the result is floored to an integer as well. This is the same behavior you're observing earlier with -1/4.
If you want a non-integer result, one or both of the operands have to be floats. For example:
0 - 1 / 4.to_f
to_f makes the interpreter interpret the number as a float.
edit: Your calculation is wrong, by the way. 0 - 1/4 is NOT the same as (0-1) / 4. Always do your operations in the correct order!
Because 1 / 4 is 0. And 0 - 0 is 0.
0 - (1 / 4)
You want this:
(0 - 1) / 4
This way you make sure that subtraction happens first. Read up on operator precedence.

Resources