"wrong number of arguments" ArgumentError when using round - ruby

I am trying to convert a temperature from Fahrenheit to Celsius:
puts 'Convertir grados Fahrenheit a Celcius'
STDOUT.flush
x = gets.chomp
aprox = (x * 100.0).round(2) / 100.0
resultado = (aprox-32)/1.8
puts resultado
I use the correct formula for converting Fahrenheit to Celcius:
Celsius = Fahrenheit - 32 / 1.8
However, when I run this in the console, it gives me the following error:
`round': wrong number of arguments (1 for 0) (ArgumentError)
I've tried different things but I don't understand why this doesn't work.

In ruby version prior to 1.9.0 round does not take arguments. It rounds to the nearest integer (see the documentation about floats and the use of round)
Use this instead:
aprox = (x * 100).round() / 100.0
The whole point of multiplying and dividing by 100 is to round the last two digit of x.

You don't specify what version of Ruby you are using. That makes a difference, because in Rubies prior to 1.9 Float#round did not take a parameter. In 1.9+ it does.
>> RUBY_VERSION #=> "1.9.2"
>> pi = 3.141 #=> 3.141
>> pi.round #=> 3
>> pi.round(1) #=> 3.1
>> 3.141.round(1) #=> 3.1

activesupport (part of rails) also gives you Float#round(precision)

Related

what does the number 1e18 in ruby mean

I am trying to replace the number 18 in 1e18 with a variable but everything I have tried gives an error. Perhaps if I knew what it does I can be able to write the formula myself differently.
What does the letter 3 do to a number. How can I apply it to a variable called, say, X?
How different is e from **
what does the number 1e18 in ruby mean?
1e18 (or 1E18) is a number literal using E-notation. Ruby interprets this number as a floating point number with the value 1 × 1018 (i.e. 1,000,000,000,000,000,000).
I am trying to replace the number 18 in 1e18 with a variable
1e18 is equivalent to:
1.0 * 10 ** 18
#=> 1.0e+18
so you can write:
x = 18
1.0 * 10 ** x
#=> 1.0e+18
or simply:
10.0 ** x
#=> 1.0e+18
How different is e from **
The result is the same, but 1e18 – being a literal – is evaluated by the parser whereas ** is a method call.
As Sami's comment mentions:
1e18 is a scientific notation meaning 1 * 10^18
Read more about the number here
How to work with such numbers in Ruby?
Here's a simple example:
require 'bigdecimal'
a = BigDecimal.new "1e18"
#=> #<BigDecimal:2cf0880,'0.1E19',9(18)>
a.to_f
#=> 1.0e+18
a.to_s
#=> "0.1E19" # notice 0.1E19 and not 1.0E19
"%f" % a
#=> "1000000000000000000.000000"
("%f" % a).to_i
#=> 1000000000000000000

How do I write a math formula?

I need to write the following formula in code:
C ((i/100)(n/365)+1)
This means that i should be divided by 100, n should be divided by 365, both results must be multiplied, the resulting number should be added 1 and the resulting number should be multiplied by C.
I was able to write the following code, but there is an error in the math operation I cannot fix:
puts "Insert money to invest:"
money_invested = gets.to_i
puts "Indicate in days the period of deposit:"
time_investment = gets.to_i
puts "Indicate interest rate:"
interest_rate = gets.to_i
investment_calculation = money_invested * (([interest_rate / 100] [time_investment / 365]) + 1)
puts "Your refund will be $#{investment_calculation.round(2)}."
try this:
investment_calculation = money_invested * (((interest_rate / 100) * (time_investment / 365) + 1))
1) you used [] instead of ().
in ruby [] corresponds to a list
2) you need to use * to multiply the results of (interest_rate / 100) and (time_investment / 365)
EDIT
If you are using decimals your code wouldn't work, you would need to use to_f instead of to_i
like this: interest_rate = gets.to_f
When you divide two integers in Ruby, you get integer division (the result is an integer):
irb(main):001:0> 1343/1000
#=> 1
If you want a floating point number, then you need at least one of the two numbers to be a floating point value:
irb(main):002:0> 1343/1000.0
#=> 1.343
irb(main):003:0> 1343.0/1000
#=> 1.343
You can do this by making the user input into floating point numbers instead of integers (use to_f instead of to_i), or by using floating point constants in your formula. The first will suffice, and makes sense, in case the user types in 50.75 for their money. ("50.75".to_i #=> 50)
puts "Insert money to invest:"
money_invested = gets.to_f
puts "Indicate in days the period of deposit:"
time_investment = gets.to_f
puts "Indicate interest rate:"
interest_rate = gets.to_f
investment_calculation = money_invested * (1 + interest_rate/100 * time_investment/365)
puts "Your refund will be $%.2f." % investment_calculation
Note that I've used String#% method with %.2f to format your number to two decimals. This is because 3.round(2) yields the number 3.0 and not the string "3.00" as you desire.

Ruby: How to check for negative zero

How can I find out if a Float value is a negative zero (and not a positive one)?
Unfortunately:
-0.0 == 0.0 # => true
-0.0 === 0.0 # => true
My initial solution works but is ugly:
x.to_s == '-0.0'
From this question, I found
x == 0 and 1 / x < 0
Is there a better, more Ruby-like way?
Ruby's BigDecimal class has a sign method that produces the correct result for negative zero. You can convert a Float to a BigDecimal with the to_d method if you require 'bigdecimal/util'.
require 'bigdecimal'
require 'bigdecimal/util'
0.0.to_d.sign
#=> 1
-0.0.to_d.sign
#=> -1
Combine this with zero? and you're good to go:
def negative_zero?(x)
x.zero? && x.to_d.sign == -1
end
negative_zero?(0.0)
#=> false
negative_zero?(-0.0)
#=> true
The angle method (and it's aliases arg and phase) returns zero for positive floats and Pi for negatives.
p 0.0.angle #=> 0
p -0.0.angle #=> 3.141592653589793
In Ruby the Float equality operator for -0.0 and 0.0 returns true, as per ordinary arithmetic.
However if you convert the two floats to bytes using little-endian or big-endian byte order, you'll see they do not in fact match.
[-0.0].pack('E')
#=> "\x00\x00\x00\x00\x00\x00\x00\x80"
[0.0].pack('E')
#=> "\x00\x00\x00\x00\x00\x00\x00\x00"
[-0.0].pack('E') == [0.0].pack('E')
#=> false
If your purpose is to prevent "negative zero", then this is how rails does it:
number = number.abs if number.zero?
Cause ruby determines them as the same object the only way to detect it by "-" sign after string conversion, as you described: -0.0.to_s.start_with?('-').

Unable to understand the subtraction result

I executed the following line in Ruby (Aptana IDE)
puts 3.3 - 2.7 == 0.6 #which should be true
and I got the result as
false
Then I executed
puts 3.3 - 2.7
and got the result as
0.5999999999999996
Can anybody please explain about whats going on? Why I got 0.5999999999999996 instead of 0.6?
Floating-point numbers cannot precisely represent all real numbers, and floating-point operations cannot precisely represent true arithmetic operations, this leads to many surprising situations.
I advise to read: https://en.wikipedia.org/wiki/Floating_point#Accuracy_problems
The right way to handle this in Ruby is to use the BigDecimal class
> require 'bigdecimal'
true
> a = BigDecimal.new('3.3')
3.3
> b = BigDecimal.new('2.7')
2.7
> c = BigDecimal.new('0.6')
0.6
> a - b == c
true
It's floating point math. Computers can't represent some values exactly. You can use Ruby's String format to get a string version:
'%0.1f' % (3.3 - 2.7) # => "0.6"
Or adjust your math to multiply your values by the precision you want, then remove that offset:
(3.3 * 10 - 2.7 * 10) / 10 # => 0.6
The question you should ask yourself (or yourinterpreter) is
how is 0.6 different from 0.5999999999999996 in my machine?
and the answer is that it is not different. Floating point number 0.5999999999999996 is 0.6 in your machine because the precision your interpreter is using for floating point numbers can not distinguish the two.
If this representation causes problems you can use explicit rounding Float#round
(3.3 - 2.7).round(1)
#=> 0.6
or special formatting (check Kernel#sprintf for more opts)
"%0.1f" % (3.3 - 2.7)
#=> "0.6"

Why is division in Ruby returning an integer instead of decimal value?

For example:
9 / 5 #=> 1
but I expected 1.8. How can I get the correct decimal (non-integer) result? Why is it returning 1 at all?
It’s doing integer division. You can use to_f to force things into floating-point mode:
9.to_f / 5 #=> 1.8
9 / 5.to_f #=> 1.8
This also works if your values are variables instead of literals. Converting one value to a float is sufficient to coerce the whole expression to floating point arithmetic.
It’s doing integer division. You can make one of the numbers a Float by adding .0:
9.0 / 5 #=> 1.8
9 / 5.0 #=> 1.8
There is also the Numeric#fdiv method which you can use instead:
9.fdiv(5) #=> 1.8
You can check it with irb:
$ irb
>> 2 / 3
=> 0
>> 2.to_f / 3
=> 0.666666666666667
>> 2 / 3.to_f
=> 0.666666666666667
You can include the ruby mathn module.
require 'mathn'
This way, you are going to be able to make the division normally.
1/2 #=> (1/2)
(1/2) ** 3 #=> (1/8)
1/3*3 #=> 1
Math.sin(1/2) #=> 0.479425538604203
This way, you get exact division (class Rational) until you decide to apply an operation that cannot be expressed as a rational, for example Math.sin.
Change the 5 to 5.0. You're getting integer division.
Fixnum#to_r is not mentioned here, it was introduced since ruby 1.9. It converts Fixnum into rational form. Below are examples of its uses. This also can give exact division as long as all the numbers used are Fixnum.
a = 1.to_r #=> (1/1)
a = 10.to_r #=> (10/1)
a = a / 3 #=> (10/3)
a = a * 3 #=> (10/1)
a.to_f #=> 10.0
Example where a float operated on a rational number coverts the result to float.
a = 5.to_r #=> (5/1)
a = a * 5.0 #=> 25.0

Resources