Without Converting to a String, How Many Digits Does a Fixnum Have

Without Converting to a String, How Many Digits Does a Fixnum Have?

puts Math.log10(1234).to_i + 1 # => 4

You could add it to Fixnum like this:

class Fixnum
def num_digits
Math.log10(self).to_i + 1
end
end

puts 1234.num_digits # => 4

What does the .size on number mean in ruby?

I always suggest to check the method you're not sure about using the following scheme:

  1. Check where the method comes from (using Object#method):

    number.method(:size)
    #=> #<Method: Fixnum#size>
  2. 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.

Why is my string converting into a Fixnum when using .to_i rather than an integer?

There's no such thing int in Ruby. Fixnum is the class of small numbers like 1 or 2 that fit into a machine word, and it's a subclass of Integer. Check the following:

irb(main):004:0> 42.class
=> Fixnum
irb(main):005:0> 42.is_a? Fixnum
=> true
irb(main):006:0> 42.is_a? Integer
=> true
irb(main):007:0> 42.is_a? Numeric
=> true
irb(main):008:0> 42.is_a? Object
=> true

So your value is a Fixnum, an Integer, a Numeric and an Object at the same time ;) This effect is called polymorphism and it might surprise you in this context because in some other programming languages numbers are treated in a special way (they have some kind of "native" type). In Ruby, numbers are just objects.

Ruby no implicit conversion of Fixnum into String (TypeError)... to_i not working

Your error is a result of trying to add string "" with number num.

Unlike JavaScript, which will try to convert types, Ruby does not allow you to use different types with math operators (unless they are numerical, such as float or integer).

Correct line 2 to say: sum = 0.

No implicit conversion of Fixnum into String, though to_i is used

You can't add a number to a string in ruby. You have to make it a string.

puts 'Hello, what\' your favorite number?'
number = gets.to_i
puts 'Here\' a better bigger favorite number - ' + (number + 1).to_s
# or
bigger_number = number + 1
puts 'Here\' a better bigger favorite number - ' + bigger_number.to_s
# or
puts "Here's a better bigger favorite number - #{bigger_number}"

Size of numeric data types in Ruby

I know that Ruby has Float for real, Fixnum and Bignum for int.

This is not true.

Float does not represent real numbers, it represents floating point numbers. In fact, in the general case, representing real numbers in a physical computer is impossible, as it requires unbounded memory.

Fixnum and Bignum are not part of Ruby. Ruby only has Integer. The Ruby Specification allows different implementations to have implementation-specific subclasses, but these are then specific to that particular implementation (e.g. YARV, Opal, TruffleRuby, Artichoke, JRuby, IronRuby, MRuby, etc.), they don't have anything to do with Ruby.

In fact, even knowing the implementation is not enough, you have to know the exact version. For example, YARV had Fixnum and Bignum as subclasses in the past, but now it doesn't anymore, it only has Integer. And even back when it had them, that was still not enough, because they actually had different sizes depending on the platform.

But what about sizes of this types?

a = 1.23 // size of one Float in bytes?

b = 1 // size of one Fixnum in bytes?

c = 2**65 // = size of one Bignum in bytes?

I am trying to find a standard or specification

Here is what the ISO/IEC 30170:2012 Information technology — Programming languages — Ruby specification has to say on the matter [bold emphasis mine]:

15.2.8 Integer

15.2.8.1 General description

Instances of the class Integer represent integers. The ranges of these integers are unbounded. However the actual values computable depend on resource limitations, and the behavior when the resource limits are exceeded is implementation-defined.

[…]

Subclasses of the class Integer may be defined as built-in classes. In this case:

  • The class Integer shall not have its direct instances. Instead of a direct instance of the class Integer, a direct instance of a subclass of the class Integer shall be created.
  • Instance methods of the class Integer need not be defined in the class Integeritself if the instance methods are defined in all subclasses of the class Integer.
  • For each subclass of the class Integer, the ranges of the values of its instances may be bounded.

The ISO Ruby Language Specification does not mandate any particular size or representation for Integers, nor does it specify any methods for querying this information.

15.2.9 Float

15.2.9.1 General description

Instances of the class Float represent floating-point numbers.
The precision of the value of an instance of the class Float is implementation-defined; however, if the underlying system of a conforming processor supports IEC 60559, the representation of an instance of the class Float shall be the 64-bit double format as specified in IEC 60559, 3.2.2.

The ISO Ruby Language Specification does not mandate any particular size or representation for Floats, unless the underlying system supports ISO/IEC 60559, in which case the representation must be as an ISO/IEC 60559 binary64 double float. The ISO Ruby Language Specification does not specify any methods for querying this information.

The ruby/spec does not say anything about the size or precision of Float. In fact, it is very careful to not say anything. For example, if you look at the spec for Float#prev_float, you can see that they are very careful to specify the behavior of Float#prev_float without ever referring to the actual precision.

The ruby/spec for Integer#size does say something about the sizes of specific machine integers in bytes. However, unfortunately, ruby/spec is kind of a mixture between specifications for the behavior of the Ruby Programming Language and the behavior of the YARV Ruby Implementation. I have the feeling that this spec is more like the latter.

For example, the cutoff point between fixnums and bignums in YARV is 231 on 32 bit platforms and 263 on 64 bit platforms, but on JRuby, it is 264 on both 32 bit and 64 bit platforms (and I think TruffleRuby is the same). So, 3000000000 will be a bignum on 32 bit YARV, but a fixnum on 64 bit YARV and JRuby, and 10000000000000000000 will be a bignum on both 32 bit and 64 bit YARV, but will be a fixnum even on 32 bit JRuby. For Opal, I think the cutoff point is different again, I think it is 253. Other implementations may not even distinguish between fixnums and bignums at all, or they may have three or more different kinds of integers.

Also, it is very important to remember that this spec only specifies the return value of the method Integer#size. Nowhere does it say that this is actually how an Integer must be represented in memory.

By the way, you may be confused why I am talking about fixnums and bignums in YARV, when I said above that Fixnum and Bignum have been removed from YARV. Well, the reason is that the separate classes have been removed, but the optimization is still there. Which is another thing: the ISO Ruby Language Specification says that you are allowed to have implementation-specific subclasses of Integer, but it doesn't say what those classes are for. Neither does the ISO Ruby Language Specification force implementors to have optimized implementations for their subclasses, nor does it force implementors to have subclasses for their implementation-specific optimizations.

Compare that to YARV's flonums which are an optimized representation of 62 bit Floats, but they don't have their own class.

So, in (not so) short: the ISO Ruby Language Specification does not say anything about the sizes of Integers, but it does say that if the underlying system supports ISO/IEC 60559, then the representation must be an ISO/IEC 60559 binary64 double float. It does, however, say nothing about the size or representation for cases where the underlying system does not support ISO/IEC 60559.

The ruby/spec is careful not to specify anything about the sizes of Floats, but it does specify the return value of the Integer#size method. It does, however, not specify that this return value must in any way correspond to how Integers are actually represented.

Here's what the RDoc for Integer#size in YARV has to say [bold emphasis mine]:

sizeint

Returns the number of bytes in the machine representation of int (machine dependent).

So, it only says that it returns the number of bytes the Integer would have in the machine representation, but not that this is necessarily the way that it is actually represented. And it clearly states that the value is machine dependent.

Error when printing string.length

Use interpolation "#{}" in Ruby. It will evaluate your expression and print your string:

#!/usr/bin/ruby
Name = "Edgar Wallace"
name = "123456"

puts "My name has #{Name.length} characters."

Note: You can not use interpolation if you are using a string with single quotes('). Use it with double quotes.

Array TypeError: can't convert Fixnum into String

You can't add a string and a integer (Fixnum), in this case you tried to add 6 to "Banana".

If on line 9 you did this:

puts array2[0] + " " + array2[1].to_s

You would get:

"Banana 6"

get each individual number from a Fixnum integer Ruby on Rails

You can convert to a string and then split into digits e.g.

first, second = User.age.to_s.split('')
=> ["2", "5"]

If you need the individual digits back as Fixnums you can map them back e.g.

first, second = User.age.to_s.split('').map { |digit| digit.to_i }
=> [2, 5]

Alternatively, you can use integer division e.g.

first, second = User.age.div(10), User.age % 10
=> [2, 5]

Note that the above examples are using parallel assignment that you might not have come across yet if you're new to Ruby.



Related Topics



Leave a reply



Submit