Convert_Words_to_Numbers Comparing Userdata Result

Posted by Xvordan on Tue 14 May 2019 10:42 AM — 6 posts, 21,263 views.

#0
I'm trying to use the words_to_numbers.lua functions to convert a word into a number, but the function returns a result that's of a userdata type. I can't use this variable type in if statements and other number comparisons. Is there an easy way to convert this variable type to a proper integer? The tonumbers() function apparently only works on strings.
USA Global Moderator #1
Please show what you're doing.
Amended on Tue 14 May 2019 11:46 AM by Fiendish
#2
require "words_to_numbers"
x = convert_words_to_numbers("one thousand three hundred and eighty four")
Note(x) -- 1384
Note(tonumber(x)) -- nil
if x > 1000 then
Note("x is bigger than 1000.")
end

Run-time error
World: Godwars2
Immediate execution
[string "Immediate"]:3: attempt to compare number with userdata
stack traceback:
[string "Immediate"]:3: in main chunk

I'd just like to convert x to an integer value that I can use in if statements against another number.
Amended on Tue 14 May 2019 12:24 PM by Xvordan
#3
Found the solution to my own problem. I'd forgotten that I had written some scripts to convert huge numbers into more easily digestable versions, and those scripts used bc.tonumber(). I has been a few years since I messed with the bc module, so forgot it could do that.
USA Global Moderator #4
Interesting. I believe that this should be considered a bug in the function.

In the meantime, you can use

tonumber(tostring(convert_words_to_numbers("one thousand three hundred and eighty four")))

or

bc.tonumber(convert_words_to_numbers("one thousand three hundred and eighty four"))


instead of


convert_words_to_numbers("one thousand three hundred and eighty four")
Amended on Tue 14 May 2019 08:18 PM by Fiendish
Australia Forum Administrator #5
The result from convert_words_to_numbers is necessarily a big number because it is designed to handle huge numbers.

All you have to do is run "tostring" on it to convert it back to a string (rather than userdata). Then you can run "tonumber" on that string, assuming it isn't too large.

For example:


require "words_to_numbers"
x = tonumber (tostring (convert_words_to_numbers("one thousand three hundred and eighty four")))
print (x)
if x > 1000 then
  Note("x is bigger than 1000.")
end


Alternatively:


require "words_to_numbers"
x = convert_words_to_numbers("one thousand three hundred and eighty four")
Note(x) -- 1384
x = tonumber (tostring (x))
Note(x) -- 1384
if x > 1000 then
   Note("x is bigger than 1000.")
end


The bignumber has an automatic "tostring" metatable entry on the userdata, so trying to print or Note it works (it converts it to a string under the hood). However comparisons don't call that as you can't compare numbers to strings.




This is pretty-much what Fiendish said, but I wanted to explain why it does that.