Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby Ruby Foundations Numbers Currency

Rogelio Valdez
Rogelio Valdez
6,244 Points

How two check if a number was entered using BigDecimal?

Hi,

I am doing the extra credit for numbers section in the Ruby basic course. I need to ask for two numbers, then multiply them and return a number with two decimal points even if no decimals was submitted.

I think I already resolved the exercise, but I was wondering how can I check if what the user entered is a number (since BigDecimal converts strings to 0.00) and if I use "nan?" (not a number) then it says it is false since 0.00 is a number. Then instead of converting the input of the user to big decimal directly I tried formatting the user input to string and then to big decimal but I am having a hard time with this.

How do I check if what the user entered is a number? If there is an exception how do I catch it to give the user another chance of entering a number? What is the best practice for doing this?

require "bigdecimal"
require "bigdecimal/util"

puts "Tell me one number."
a = gets.chomp
first_number = a.to_d

puts "Tell me another number."
b = (gets.chomp)
second_number = b.to_d

result = first_number * second_number
puts "Their multiplication is"
puts "truncated result #{'%.2f' % result.truncate(2)}"
puts 'rounded result %.2f' % result

1 Answer

Tom Sager
Tom Sager
18,987 Points

To be concise, BigDecimal converts 'invalid' strings to 0.0, e.g.

BigDecimal.new('xyz') =>  0.0              # invalid
BigDecimal.new("12.345")   => 0.12345E2   # valid

If you want to accept "0" as a legal input value, I think you will have to look at the original string to determine if it was valid. A simple regular expression should suffice:

pattern = Regexp.new('^[\d]*[\.]?[\d]*$')

"123" !~ pattern => false
"45.678"  !~ pattern => false
"0" !=~ pattern => false
"0.0" !~ pattern => false
"NaN" !~ pattern => true
"12.34.56" !~ pattern => true

This regexp is looking for the start of a string (^), followed by zero or more digits ([\d]), followed by zero or one dot ([.]?), followed by zero or more digits ([\d]), followed by the end of string ($). A return value of true shows an invalid input.