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?('-').
Related
Recently, I observed a very interesting result in Ruby while making use of && and & for the input combination of 0 & 1.
Can someone please explain the below output with respect to the above mentioned two operators? The below is implemented using Ruby 2.0.0-p451
2.0.0-p451 :006 > 0 && 1
=> 1
2.0.0-p451 :008 > 0 & 1
=> 0
Thank you
&& is the logical AND operator. It will be truthy, IFF both operands are truthy. And it is lazy (aka short-circuiting), which means it will stop evaluating as soon as the result has been fully determined. (So, since both operands need to be truthy, if the first operand is falsy, you already know that the result is going to be falsy, without even evaluating the second operand.) It will also not just return true or false, but rather return the operand which determines the outcome. IOW: if a is falsy, it'll return a, otherwise it'll return b:
nil && (loop {})
# => nil
# Note: the infinite loop is *not* evaluated
# Note: the return value is nil, not false
true && nil
# => nil
true && 'Hello'
# => 'Hello'
& simply calls the method &. It will do whatever the object wants it to do:
def (weirdo = Object.new).&(other)
puts 'Whoah, weird!'
'Hello, ' + other
end
weirdo & 'World'
# Whoah, weird!
# => 'Hello, World'
In general, & and its brother | are expected to perform conjunction and disjunction. So, for booleans, they are perform AND and OR (TrueClass#&, FalseClass#&, NilClass#&, TrueClass#|, FalseClass#|, NilClass#|) with the exception that & and | are standard method calls and thus always evaluate their argument and that they always return true or false and not their arguments.
For Sets, they perform set intersection and set union: Set#&, Set#|. For other collections (specifically Arrays), they also perform set operations: Array#&, Array#|.
For Integers, they perform BITWISE-AND of the two-complement's binary representation: Fixnum#&, Bignum#&, Fixnum#|, Bignum#|.
&& is a boolean and. It returns the second argument if the first argument is true-ish. Because 0 is true-ish in Ruby, 1 is returned.
& is a bitwise and. It compares the bit representation of the values. Because (imaging 8 bit) 00000000 (0) and 00000001 (1) have no 1 digits in common, 00000000 (0) is returned.
This page gives a good explanation of the different operators in Ruby.
&& is logical AND operator in ruby.
> a = true
> b = true
> c = false
> a && b
=> true
> a && c
=> false
& is the bitwise AND operator in ruby. Per the wikipedia article on the description for the "bitwise AND operator":
A bitwise AND takes two binary representations of equal length and
performs the logical AND operation on each pair of corresponding bits.
The result in each position is 1 if the first bit is 1 and the second
bit is 1; otherwise, the result is 0.
One is a boolean operator, the other is a bitwise operator:
# Bitwise operators
a = 78 # 01001110
b = 54 # 00110110
puts (a&b) # 00000110 = 6
puts (a|b) # 01111110 = 126
puts (a^b) # 01111000 = 120
puts (~a) # 10110001 = -79
puts (a<<2) # 00111000 = 312
puts (a>>2) # 00010011 = 19
http://www.public.traineronrails.com/courses/ruby/pages/008-rubyoperators.html
&& is logical and. Which is to say, a && b returns true if a is true and b is true. & is bitwise and. In (almost) any other language, logical and of 0 and 1 would be 0, because (almost) all other languages consider 0 to be false. But in ruby, anything except nil and false are considered to be truthy.
&& is a Logical operator which will always return a boolean value.
z It's either true if both of the values are true
true && true
and will return false if any of the value is false
false && true
Now comes to second point & Operator.
Here are two answer for the & Operator.
& is a Bitwise operator as mentioned in above answers, It compares bit representation in the form of 0 and 1.
Another Important answer is, In upgradation of Ruby 2.6 its implementation is somewhat modified.
& is represented as intersection operator
For ex:
[1, 2, 3] & [2, 3, 4]
$ [2, 3]
I can get Infinity and NaN by
n = 9.0 / 0 #=> Infinity
n.class #=> Float
m = 0 / 0.0 #=> NaN
m.class #=> Float
but when I want to access Infinity or NaN directly:
Infinity #=> uninitialized constant Infinity (NameError)
NaN #=> uninitialized constant NaN (NameError)
What are Infinity and NaN? Are they objects, keywords, or something else?
What you see printed as Infinity and NaN are just the string representations for two special instances of the Float class, not keywords or literals. They are returned by floating point division by 0 or by referencing the constants Float::INFINITY and Float::NAN.
Float::INFINITY.class
# => Float
Float::INFINITY.to_s
# => "Infinity"
Float::NAN.class
# => Float
Float::NAN.to_s
# => "NaN"
If you want inf/nan literal, use follow:
>> Float::INFINITY
=> Infinity
>> Float::NAN
=> NaN
See Float constants list
the code below outputs 0.0. is this because of the overflow? how to avoid it? if not, why?
p ((1..100000).map {rand}).reduce :*
I was hoping to speed up this code:
p r.reduce(0) {|m, v| m + (Math.log10 v)}
and use this instead:
p Math.log10 (r.reduce :*)
but apparently this is not always possible...
The values produced by rand are all between 0.0 and 1.0. This means that on each multiplication, your number gets smaller. So by the time you have multiplied 1000 of them, it is probably indistinguishable from 0.
At some point, ruby will take your number to be so small that it is 0. for instance: 2.0e-1000 # => 0
Every multiplication reduces your number by about 1/21, so after about 50 of them, you are down 1/250, and after 100000 (actually, after about 700) you have underflowed the FP format itself, see here.
Ruby provides the BigDecimal class, which implements accurate floating point arithmetic.
require 'bigdecimal'
n = 100
decimals = n.times.map { BigDecimal.new rand.to_s }
result = decimals.reduce :*
result.nonzero?.nil? # returns nil if zero, self otherwise
# => false
result.precs # [significant_digits, maximum_significant_digits]
# => [1575, 1764]
Math.log10 result
# => -46.8031931083014
It is a lot slower than native floating point numbers, however. With n = 100_000, the decimals.reduce :* call went on for minutes on my computer before I finally interrupted it.
I need help for understanding - What is the difference between Equal to and Comparison?
Here is the case
x == y means `Equal to`
x = 10 and y = 10
puts "X and Y are equal" if x == y
puts "X and Y are equal" if x <=> y
I know when and where can I use equal to, but when and where can I use Comparison <=>
Thanks
When you want to compare? It returns -1, 0, 1. For example, sorting users by first name:
users_by_first = users.sort { |u1, u2| u1.fname <=> u2.fname }
Here's another SO question asking about the spaceship operator.
<=> General comparison operator. Returns -1, 0, or +1, depending on whether its receiver is less than, equal to, or greater than its argument.
http://ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html
This is useful for sorting, for one thing.
Equality operators: == and !=
The == operator, also known as equality or double equal, will return true if both objects are equal and false if they are not.
"koan" == "koan" # Output: => true
The != operator, AKA inequality or bang-tilde, is the opposite of ==. It will return true if both objects are not equal and false if they are equal.
"koan" != "discursive thought" # Output: => true
Note that two arrays with the same elements in a different order are not equal, uppercase and lowercase versions of the same letter are not equal and so on.
When comparing numbers of different types (e.g., integer and float), if their numeric value is the same, == will return true.
2 == 2.0 # Output: => true
Comparison operators
Objects such as numbers and strings, which can be compared (amongst themselves) in terms of being greater or smaller than others, provide the <=> method, also known as the spaceship method. When comparing two objects, <=> returns -1 if the first object is lesser than the second (a < b), 0 in case they are equal (a == b) and 1 when the first object is greater than the second (a > b).
5 <=> 8 # Output: => -1
5 <=> 5 # Output: => 0
8 <=> 5 # Output: => 1
Most comparable or sortable object classes, such as Integer, Float, Time and String, include a mixin called Comparable, which provides the following comparison operators: < (less than), <= (less than or equal), == (equal), > (greater than), >= (greater than or equal). These methods use the spaceship operator under the hood.
Comparison operators can be used in objects of all the above classes, as in the following examples.
# String
"a" < "b" # Output: => true
"a" > "b" # Output: => false
# Symbol
:a < :b # Output: => true
:a > :b # Output: => false
# Fixnum (subclass of Integer)
1 < 2 # Output: => true
2 >= 2 # Output: => true
# Float
1.0 < 2.0 # Output: => true
2.0 >= 2.0 # Output: => true
# Time
Time.local(2016, 5, 28) < Time.local(2016, 5, 29) # Output: => true
When comparing numbers of different classes, comparison operators will implicitly perform simple type conversions.
# Fixnum vs. Float
2 < 3.0 # Output: => true
2.0 > 3 # Output: => false
More info about Ruby operators is available at this blog post.
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