Skip to content

power and fix methods#1

Open
suleman-uzair wants to merge 6 commits intomasterfrom
update/plurimath-js/bigdecimal-methods
Open

power and fix methods#1
suleman-uzair wants to merge 6 commits intomasterfrom
update/plurimath-js/bigdecimal-methods

Conversation

@suleman-uzair
Copy link
Copy Markdown
Member

This PR adds the support power and fix methods for consistency with BigDecimal-Ruby.

related to => plurimath/plurimath-js#28

hmdne and others added 4 commits November 25, 2023 07:38
We had a wrong logic assuming, that low surrogate comes before
the high surrogate, while the reverse is true. This caused an
errorneus output of `String#chars` function etc. while iterating
over character that is over the BMP, that is, has a Unicode
codepoint over 0xffff.
A little known thing about JavaScript is that it uses UTF-16
encoding for its strings. But to leverage full extent of UTF-16
support, one must use correct functions, otherwise we are left
with not supported over-the-BMP characters, like now ubiquitous
emoji.

This commit also makes most regexps use Unicode mode. Due to the
Unicode mode regexps being more strict, we now really need a half
a decent transpiler. That's also what it adds and using that
situation, we also add support for POSIX character classes, which
are quire often used in Ruby, but aren't there in JS, so we simulate
them with Unicode character classes.

As a side effect, this made us support value omission for hashes
when compiling with Opal in JS (eg. when using `eval`). Since all
the MSpec tests do this, we pass the tests now.

We also add a proper support for multiline regular expressions.
Semantics between how multiline works in Ruby and JS is very big,
as in, those are basically two different features. This commit
aims to reconcile those two features in the most straightforward
way. This commit introduces quite proper handling of all "\A",
"\z", "$", "^". It is our opinion, that a regexp will contain
only one set of those in which case things will work correctly.
If not, then we launch a warning.

Regexps are now annotated if needed. This means, that if a certain
regexp has been transpiled and the transpilation result differs,
the copy of the original Regexp will be preserved, so that further
manipulations on that Regexp, for instance `Regexp.union`, will
work on an original Regexp.

This PR has been sponsored by Ribose Inc.
@ronaldtse
Copy link
Copy Markdown

@hmdne are you okay with this? Thanks!

@hmdne
Copy link
Copy Markdown

hmdne commented Jan 7, 2025

Looks good to me. I will backport it to the opal/opal repo and try to see if we can enable some more rubyspec tests.

@hmdne
Copy link
Copy Markdown

hmdne commented Jan 7, 2025

In short, all is fine, a couple of additional Rubyspec tests are passing now (https://github.com/ruby/spec/tree/ee83ee683bf15bb2bdd98498069f298abefbdbcc is the repo):

  fails "BigDecimal#** 0 to power of 0 is 1" # NoMethodError: undefined method `**' for 0
  fails "BigDecimal#** 0 to powers < 0 is Infinity" # NoMethodError: undefined method `**' for 0
  fails "BigDecimal#** other powers of 0 are 0" # NoMethodError: undefined method `**' for 0
  fails "BigDecimal#** powers of 1 equal 1" # NoMethodError: undefined method `**' for 1
  fails "BigDecimal#** returns 0.0 if self is infinite and argument is negative" # NoMethodError: undefined method `**' for Infinity
  fails "BigDecimal#** returns NaN if self is NaN" # NoMethodError: undefined method `**' for NaN
  fails "BigDecimal#** returns infinite if self is infinite and argument is positive" # NoMethodError: undefined method `**' for Infinity
  fails "BigDecimal#fix correctly handles special values" # NoMethodError: undefined method `fix' for Infinity
  fails "BigDecimal#fix does not allow any arguments" # Expected ArgumentError but got: NoMethodError (undefined method `fix' for 1.23456789)
  fails "BigDecimal#fix returns 0 if the absolute value is < 1" # NoMethodError: undefined method `fix' for 0.99999
  fails "BigDecimal#fix returns a BigDecimal" # NoMethodError: undefined method `fix' for Infinity
  fails "BigDecimal#fix returns the integer part of the absolute value" # NoMethodError: undefined method `fix' for 2e+1000
  fails "BigDecimal#power 0 to power of 0 is 1" # NoMethodError: undefined method `power' for 0
  fails "BigDecimal#power 0 to powers < 0 is Infinity" # NoMethodError: undefined method `power' for 0
  fails "BigDecimal#power other powers of 0 are 0" # NoMethodError: undefined method `power' for 0
  fails "BigDecimal#power powers of 1 equal 1" # NoMethodError: undefined method `power' for 1
  fails "BigDecimal#power returns 0.0 if self is infinite and argument is negative" # NoMethodError: undefined method `power' for Infinity
  fails "BigDecimal#power returns NaN if self is NaN" # NoMethodError: undefined method `power' for NaN
  fails "BigDecimal#power returns infinite if self is infinite and argument is positive" # NoMethodError: undefined method `power' for Infinity

But also there are new failures, which probably were disabled due to missing functions, some of which you may want to correct for better compatibility.

fails "BigDecimal#truncate returns NaN if self is NaN" # ArgumentError: [BigDecimal#fix] wrong number of arguments (given 1, expected 0)
fails "BigDecimal#truncate returns value of type Integer." # Expected false == true to be truthy but was false
fails "BigDecimal#truncate sets n digits left of the decimal point to 0, if given n < 0" # ArgumentError: [BigDecimal#fix] wrong number of arguments (given 1, expected 0)

@suleman-uzair
Copy link
Copy Markdown
Member Author

@hmdne, I have fixed the argument error, and now there is an error related to BigNumber’s support for negative integers as the truncate method’s argument.
As far as I could explore the BigNumber v2.1.4, the minimum integer allowed for round (called in truncate) is 0, while BigDecimal supports negative integers.

for example In Ruby:

BigDecimal("1212.11").truncate(-1).to_s("F") # "1210.0"

But in BigNumber this will raise the following error (as mentioned here):

decimal places out of range

can we skip the negative integers support for now or do we need this implementation?

cc: @ronaldtse

@hmdne
Copy link
Copy Markdown

hmdne commented Jan 14, 2025

@suleman-uzair We need as much as is required for you to proceed with the work on Plurimath, anything more will likely help us in the future, but is not required. I will backport things upstream tomorrow.

@suleman-uzair
Copy link
Copy Markdown
Member Author

suleman-uzair commented Jan 15, 2025

Thank you @hmdne, this works for me.

@ronaldtse, this PR is finalized, let me know if I should merge this.

@hmdne
Copy link
Copy Markdown

hmdne commented Jan 17, 2025

@suleman-uzair We have merged your patch to upstream Opal. In the future we can rebase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants