// this finds the average of all the floats in attack/speedValues,
// then does average += average * 0.8 or 0.5, and rounds it up to the
// tenths place. the resulting value is the attackDamage/speedBaseline.
var attack = new BigDecimal("0");
for (final var f : attackValues) {
attack = attack.add(new BigDecimal(Float.toString(f)));
}
attack = attack.divide(new BigDecimal(Integer.toString(attackValues.size())), 3, CEILING);
attackDamageBaseline = attack.add(attack.multiply(BigDecimal.valueOf(.08)))
.setScale(1, CEILING).floatValue();
```i want to make this to not have bigdecimals so it has better performance, but idk how i would do that (i want the same result +-0.1)
#how would i change this to not have bigdecimals
1 messages · Page 1 of 1 (latest)
Detected code, here are some useful tools:
<@&987246399047479336> please have a look, thanks.
While you are waiting for getting help, here are some tips to improve your experience:
If nobody is calling back, that usually means that your question was not well asked and hence nobody feels confident enough answering. Try to use your time to elaborate, provide details, context, more code, examples and maybe some screenshots. With enough info, someone knows the answer for sure.
Don't forget to close your thread using the command </help-thread close:1027500463647621170> when your question has been answered, thanks.
Why do you use BigDecimal currently? Are you expecting very large values?
You could try just using normal primitives, and see if it produces a good result
new BigDecimal(Float.toString(f))
This is not a good way to do this, the documentation for that BigDecimal constructor says:
Translates the string representation of a BigDecimal into a BigDecimal.
You can just castfto adouble
Same applies to this Integer.toString(attackValues.size())
This can be replaced with just attackValues.size()
The second parameter in setScale is the roundingMode, why do you put in a variable called CEILING?
setScale(int newScale, int roundingMode)
That is the end of my code rant ^-^
Ah that makes sense
Even using BigDecimal you can remove several allocations.
BigDecimal.ZEROinstead of a newBigDecimal- rearranging
a + a * 0.08toa * 1.08 - statically creating the
1.08BigDecimalvalue. - Multiplying before dividing (a) eliminating a scaling operation and (b) making the division a scale-1 operation (able to bail out earlier)
Leading to something like...
var attack = BigDecimal.ZERO;
for (final var f : attackValues) {
attack = attack.add(BigDecimal.valueOf(f));
}
return attack
.multiply(BD_1_08)
.divide(BigDecimal.valueOf(attackValues.size()), 1, RoundingMode.CEILING)
.floatValue();
doesnt ZERO have a scale of 0
Removing BigDecimal entirely is mostly complicated by the ceiling operation.
The first part is trivial though
var attackTotal = 0.0;
for (final var f : attackValues) {
attackTotal += f;
}
var unscaled = attackTotal * 1.08 / attackValues.size();
Because Java doesn't offer a precision-specifying ceiling operation, the easiest is probably to scale up, adjust for precision, truncate to int, and scale down.
var scaledUp = (int) (unscaled * 10 + 0.9999999);
return (scaledUp / 10.0f);
Another big gain would be to look at using float[] instead of List<Float> and eliminate all of the boxing and poor locality of reference overhead (not to mention all of the pointer storage).
would doing (float)(Math.ceil(unscaled * 10) / 10) work?
also, i dont think just adding 0.9999999 would work, because unscaled might be negative
Yeah Math.ceil might be the better option.
so my code looks like this now:```java
for (final var f : attackValues) {
attackDamageBaseline += f;
}
attackDamageBaseline /= attackValues.size();
attackDamageBaseline *= 1.08;
attackDamageBaseline = (float)(Math.ceil(attackDamageBaseline * 10) / 10);
which i simplified to:java for (final var f : attackValues) { attackDamageBaseline += f; } attackDamageBaseline = (float)(Math.ceil(attackDamageBaseline / attackValues.size() * 10.8) / 10);
With floating point, multiply then divide, to minimise arithmetic error. In your case you probably encounter a difference - but it's a good habit.