Skip to content

ExprDecimalPlaces #7953

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: dev/feature
Choose a base branch
from

Conversation

Absolutionism
Copy link
Contributor

Problem

There is no expression allowing users to get how many decimal places a number goes into. Also was requested in the linked issue.

Solution

Adds ExprDecimalPlaces allowing users to quickly and easily get how many decimal places a number goes into.

Testing Completed

ExprDecimalPlaces.sk

Supporting Information

N/A


Completes: #7948
Related: none

@Absolutionism Absolutionism requested a review from a team as a code owner June 15, 2025 22:18
@Absolutionism Absolutionism requested review from cheeezburga and erenkarakal and removed request for a team June 15, 2025 22:18
@skriptlang-automation skriptlang-automation bot added the needs reviews A PR that needs additional reviews label Jun 15, 2025
@Absolutionism Absolutionism added the feature Pull request adding a new feature. label Jun 15, 2025
Copy link
Member

@erenkarakal erenkarakal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

double.toString always contains a dot

Copy link
Member

@sovdeeth sovdeeth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fear this will have some weird behavior with floating point errors. For example:
image
If you have number accuracy high, it really does have that many decimals. But if number accuracy is set to like 2, or even 7, it will print 3.
I'm not sure this should be based off of the doublevalue.toString at all.

@skriptlang-automation skriptlang-automation bot removed the needs reviews A PR that needs additional reviews label Jun 16, 2025
@Absolutionism
Copy link
Contributor Author

I'm not sure this should be based off of the doublevalue.toString at all.

What do you suggest? I was originally going to make it:

"[the] number of decimal places of %numbers% [limited:with a (limit|cap) of %-integer%]
"[the] number of decimal places of %numbers% [unlimited:with no (limit|cap)]

So default behavior would use the number accuracy option in the config
limited would limit to the provided integer
unlimited no limit

@sovdeeth
Copy link
Member

sovdeeth commented Jun 17, 2025

I'm not sure this should be based off of the doublevalue.toString at all.

What do you suggest? I was originally going to make it:

"[the] number of decimal places of %numbers% [limited:with a (limit|cap) of %-integer%]
"[the] number of decimal places of %numbers% [unlimited:with no (limit|cap)]

So default behavior would use the number accuracy option in the config limited would limit to the provided integer unlimited no limit

Well I think you should be using Skript.toString() to convert the number to a string, which will respect the number accuracy.
Alternatively, you can forgo a toString entirely and instead repeatedly divide by 10 until x % 1 is within epsilon of 0/1.
You should try both and see how well each works

@Absolutionism
Copy link
Contributor Author

Alternatively, you can forgo a toString entirely and instead repeatedly divide by 10 until x % 1 is within epsilon of 0/1.

So something like this?

for (Number number : numbers.getArray(event)) {
	if (!(number instanceof Double doubleValue))
		continue;
	long decimalPlace = 0L;
	double x = Double.valueOf(doubleValue);
	while (Math.abs(x % 1) > 1e-9) {
		x /= 10;
		decimalPlace++;
	}
	decimalPlaces.add(decimalPlace);
}

@sovdeeth
Copy link
Member

Alternatively, you can forgo a toString entirely and instead repeatedly divide by 10 until x % 1 is within epsilon of 0/1.

So something like this?

for (Number number : numbers.getArray(event)) {
	if (!(number instanceof Double doubleValue))
		continue;
	long decimalPlace = 0L;
	double x = Double.valueOf(doubleValue);
	while (Math.abs(x % 1) > 1e-9) {
		x /= 10;
		decimalPlace++;
	}
	decimalPlaces.add(decimalPlace);
}

yes but i should have said multiply not divide
and make sure you check for the mod result being like 0.99999999

}
double x = Double.valueOf(doubleValue);
long decimalPlace = 0L;
for (int i = 0; i < limit; i++) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why have both i and decimalPlace?

also i don't think this limit thing would work very well. Take 1.00001. With accuracy set to 2, this would print as 1, but have 2 decimal places. I think you'll need to round the number to the limit first.

@@ -0,0 +1,19 @@
test "decimal places":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs tests for floating point error stuff like places of 0.3/0.1

@skriptlang-automation skriptlang-automation bot added the needs reviews A PR that needs additional reviews label Jun 19, 2025
@Absolutionism Absolutionism moved this to In Progress in 2.13 Release Jul 2, 2025
@Absolutionism Absolutionism moved this from In Progress to In Review in 2.13 Release Jul 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Pull request adding a new feature. needs reviews A PR that needs additional reviews
Projects
Status: In Review
Development

Successfully merging this pull request may close these issues.

3 participants