Why is my ruby giving incorrect size of number? It doesn't matter what's the number. The output is always 4 for the size. What does that mean? I always thought it should give the number of digits.
number = 14
print number
print "\n"
print number.size
output:
14
4
ruby version
ruby 2.1.8p440 (2015-12-16 revision 53160) [i386-mingw32]
I always suggest to check the method you're not sure about using the following scheme:
Check where the method comes from (using Object#method):
number.method(:size)
#=> #<Method: Fixnum#size>
Open docs and learn what it does for Fixnum#size and how it works.
2.1 If you're using IRB, you can run help 'Fixnum#size' to get the docs right in your console
2.2 If you're using pry, you can go with show-doc Fixnum#size (install pry-doc gem first)
In Ruby 2.1.8 method was defined in Fixnum#size.
Starting from Ruby 2.4 it's defined in
Integer#size:
Returns the number of bytes in the machine representation of int.
You are confusing the two methods String#size:
Returns the character length of str.
and Fixnum#size:
Returns the number of bytes in the machine representation of fix.
14 is an object of class Fixnum, so when you call size on it you are getting the number of bytes in the machine representation of the number.
If you would like to know how many digits there are in a number, you can simply convert it to a string first and then call size on that:
14.to_s
# => "14"
14.to_s.size
#=> 2
12345.to_s.size
#=> 5
Related
I get this for a nil object in Ruby (irb):
nil.object_id # => 4
But for a string, I get negative results:
"abc".object_id # => -570954278
"abc".object_id # => -570956148
I am confused about the negative part. Is this proper or have I done something strange?
My ruby is:
ruby 2.3.0p0 (2015-12-25 revision 53290) [i686-linux]
The number effectively is a signed integer, with one bit used for sign and the rest used for data. See here for a discussion on some finer points of its implementation, mentioning the positive and negative storage.
But to be short, no, there isn't anything to worry about.
RubyMonk makes a point on how you can use underscores for convenience to write large numbers that can become difficult to read without demarcation.
Their task is: Try using underscores to make a huge, readable number. They provide this code:
def describe(something)
puts "I am a: #{something.class} and I look like: #{something}"
end
def big_num
# create a huge number
end
describe(big_num)
Could anyone explain how I would go about creating a huge number? According to the error messages below, I have to use underscores in the code to make it pass.
RubyMonk expects a object of class Bignum, which is part of the standard Ruby library. From the documentation:
Bignum objects hold integers outside the range of Fixnum. Bignum
objects are created automatically when integer calculations would
otherwise overflow a Fixnum.
So you just have to create a number that is bigger than what Fixnum can handle. For example, this will pass RubyMonk's spec:
def big_num
5_000_000_000_000_000_000_000
end
Because the number is bigger than Fixnum can handle, Ruby automagically returns a Bignum instead. For example, try running this:
5_000_000_000.class
# => Fixnum
5_000_000_000_000_000_000_000.class
# => Bignum
Ruby allows using underscores as placeholders (i.e. they are only to increase readability for humans and are otherwise ignored). So your big_num method can simply have one line:
return 1_000_000_000_000_000_000_000_000_000_000_000
And calling that will return 1000000000000000000000000000000000
(the return keyword is optional)
Ruby allows you to put underscores while writing literal numbers so that large numbers can be easier to read.
The convention goes that you shouldn't put underscores if the number is 4 or less digits long and on every three numbers if it's longer, starting from right:
10_000_000 # => 10000000
Works for floating numbers too:
10_000.0 # => 10000.0
The underscores are ignored by the interpreter if you put them between two digits:
1_2_3_4_5 # => 12345
After looking at the error message, it is clear that RubyMonk expects Bignum. This is another magic, which the interpreter does transparently - if the number is small enough to be mapped to the architecture's int, the number is an instance of Fixnum:
100.class # => Fixnum
If that is not the case, Ruby automagically uses a dedicated class (Bignum):
(10_000_000**100).class # => Bignum
# 10_000_000 to the power of 100,
# which is a very big number and
# thus stored in Bignum
Following is my Ruby code:
"100".to_i(9) # => 81
Can somebody explain why the result is 81?
Look into radix and the String#to_i documentation. It's the base. Normal numbers are base 10. You specified base 9.
For example
x ** 3 # => 125
Knowing that the result of applying ** with an argument 3 to x is 125, how can I get the value of x?
Is there some kind of built-in method for this? I have been looking at the Math module but didn't find anything similar.
Using ** with 1/3:
125 ** (1.0/3)
# => 4.999999999999999
You could also try as below :
irb(main):005:0> 125**(3**-1)
=> 5
irb(main):006:0> 125**(3**-1.0)
=> 4.999999999999999
irb(main):007:0>
update
C:\Users >ruby -v
ruby 1.9.3p448 (2013-06-27) [i386-mingw32]
You can do an Nth root by raising to a fractional power. For example, the 4th root of 625 is 5.
(BigDecimal.new(625)**(1.0/4.0)).to_f
# => 5.0
Note, the .to_f is added for readability in this answer only. Don't cast it to a Float in your code unless you need to. IMHO, BigDecimals are "better" than Floats in Ruby - Floats lose precision too easily and you won't get accurate results. Case in point the accepted awnser above. The cube root of 125 is not 4.99999(repeat). It is 5.0 exactly.
Edit: the Ruby Class Rational seems to handle nth roots a little better.
2.3.3 :007 > 625.to_r ** 0.25
=> 5.0
But it still isn't as precise with a number that produces an irrational root.
2.3.3 :024 > (999.to_r ** 0.25) ** 4
=> 998.9999999999999
Close...but you should be able to get back to 999.0 exactly. My Mac's calculator and excel can do it. Main point - just be careful. If precision is important, Ruby may not handle this exactly the way one would expect.
The following piece of code works perfectly in script/console but returns the following error when i compile the same in a ruby script.:
:in `round': wrong number of arguments (1 for 0) (ArgumentError)
tf={"ph"=>{0=>1.33333333333333, 1=>1.5}, "fee"=>{0=>1.66666666666667}, "test"=>{0=>1.16666666666667, 1=>1.25}, "what"=>{0=>2.0, 1=>2.0}, "for"=>{0=>1.5}, "is"=>{0=>1.83333333333333, 1=>1.75}}
tf.each{|k,v| v.each{|k1,v1| tf[k][k1]=(v1.round(5))}}
Any Ideas ? Cheers !
Float#round seems to work differently in Ruby 1.8 and Ruby 1.9: in 1.8 it complains about the given argument, in 1.9 returns back float properly rounded to the given number of decimals.
But, as the article linked in the other answer wisely says:
you should consider the reason you’re
performing the rounding (or
equivalent) operation. If it’s for
presentation reasons only a better way
might be to use a format string
instead, and leave the original data
intact.
From what it looks like, you are not supposed to pass an argument to the round method. You have passed 5 to it.
If you are trying to round it to 5 decimal places, there is no builtin method for that (that I'm aware of). This is a page that explains how to do so: http://solutions.hans-eric.com/rounding-off-floating-point-numbers-in-ruby