org.javamoney.moneta.RoundedMoney - some operations result in a rounded value some are not - java-money

If i use org.javamoney.moneta and run the following program, i got some contrary results for some operations on org.javamoney.moneta.RoundedMoney. Sometimes the resulted value is rounded some times it is not.
Am I using the class wrong or is that a bug?
import java.math.BigDecimal;
import javax.money.CurrencyUnit;
import javax.money.Monetary;
import org.javamoney.moneta.RoundedMoney;
public final class RoundedMoneyRounding
{
private RoundedMoneyRounding()
{
}
public static void main(final String... args)
{
final CurrencyUnit usd = Monetary.getCurrency("USD");
final RoundedMoney halfcent = RoundedMoney.of(new BigDecimal("0.005"), usd);
final RoundedMoney zero = RoundedMoney.of(BigDecimal.ZERO, usd);
System.out.append("A1. 0.005 + 0 = ").println(//
halfcent.add(zero) //
.getNumber().numberValue(BigDecimal.class).toPlainString());
System.out.append("A2. 0 + 0.005 = ").println(//
zero.add(halfcent) //
.getNumber().numberValue(BigDecimal.class).toPlainString());
System.out.println("----");
System.out.append("B1: -0.005 = ").println(//
halfcent.negate() //
.getNumber().numberValue(BigDecimal.class).toPlainString());
System.out.append("B2: 0.005 * -1 = ").println(//
halfcent.multiply(new BigDecimal("-1")) //
.getNumber().numberValue(BigDecimal.class).toPlainString());
System.out.println("----");
System.out.append("C1: 0.005 * 1 = ").println(//
halfcent.multiply(BigDecimal.ONE) //
.getNumber().numberValue(BigDecimal.class).toPlainString());
System.out.append("C2: 0.005 * 1.1 = ").println(//
halfcent.multiply(new BigDecimal("1.1")) //
.getNumber().numberValue(BigDecimal.class).toPlainString());
System.out.println("----");
System.out.append("D1: 0.005 * 2 = ").println(//
halfcent.multiply(new BigDecimal("2")) //
.getNumber().numberValue(BigDecimal.class).toPlainString());
System.out.append("D2: (0.005 * 2) / 2 = ").println(//
halfcent.multiply(new BigDecimal("2")).divide(new BigDecimal("2")) //
.getNumber().numberValue(BigDecimal.class).toPlainString());
}
}
Output:
A1. 0.005 + 0 = 0.005
A2. 0 + 0.005 = 0
----
B1: -0.005 = -0.005
B2: 0.005 * -1 = 0
----
C1: 0.005 * 1 = 0.005
C2: 0.005 * 1.1 = 0.01
----
D1: 0.005 * 2 = 0.01
D2: (0.005 * 2) / 2 = 0
The used maven dependency is:
<dependency>
<groupId>org.javamoney</groupId>
<artifactId>moneta</artifactId>
<version>1.3</version>
<type>pom</type>
</dependency>

(Just found the corresponding issue on GitHub 😛)
This is probably due to the implementation-specific assumption that RoundedMoney instances will always contain rounded values, but, apparently, this is not enforced in the factory methods and constructors of that class. You can happily construct it with unrounded values.
When doing math with that class, some arithmetic optimizations apply: Examples A1 and C1 use the identity elements of addition and multiplication on the right hand side, hence they are effectively no-ops, and this will be returned, representing the initial unrounded value. Examples A2 and C2 could theoretically return the right hand side operator directly, but that optimization is missing, so RoundedMoney actually starts to calculate (and round) the result.
Example B1 just flips the sign of the number value. Here, the same assumptions apply: If x is a correctly rounded value, then -x is also correctly rounded[1]. So, RoundedMoney won't bother to apply the rounding to the new numeric value. In contrast, example B2 isn't optimized, but calculated and rounded.
So, I think the actual culprits are the factory methods, which won't apply the rounding to user-supplied values:
public static RoundedMoney of(BigDecimal number, CurrencyUnit currency) {
return new RoundedMoney(number, currency, Monetary.getDefaultRounding());
}
public static RoundedMoney of(BigDecimal number, CurrencyUnit currency, MonetaryOperator rounding) {
return new RoundedMoney(number, currency, rounding);
}
should most probably be
public static RoundedMoney of(BigDecimal number, CurrencyUnit currency) {
return of(number, currency, Monetary.getDefaultRounding());
}
public static RoundedMoney of(BigDecimal number, CurrencyUnit currency, MonetaryOperator rounding) {
return new RoundedMoney(number, currency, rounding).with(rounding);
}
I'd argue this is a bug, but since there's not much (no?) documentation about how that class is supposed to be used – or not used, for that matter – it might even be intended behavior?
[1]: This is interesting. Is there any rounding which won't satisfy that assumption? In fact, since RoundedMoney leverages a MoentaryOperator to apply the rounding, one could easily pass in some arbitrary "non-symmetric" operator.

Related

converting one function into multiple - Kotlin

how would I go about taking this one function and turning it into multiple functions?
I need to create a local double variable called change and set it to a test value (e.g. 44.77)
Create five separate functions dollars(), quarters(), dimes(), nickels() and pennies().
Each function will:
accept a double amount as an argument
calculate and display that denominations number (e.g. 7 Dollars)
then return the recalculated change (e.g. 0.67)
In Kotlin, the function signature for quarters would be: quarters(myChange: Double): Double
I really wish we didn't have to do separate function as one function is so much easier.
here is my code so far:
fun main(args: Array<String>) {
var remChange = .03 ;
monies(remChange);
}
fun monies(remChange: Double){
var dollars = Math.floor(remChange/1.0);
var remChange1 = remChange-(dollars*1.00);
print(Math.round(dollars*1)/1)
if(dollars<2) println("_Dollar"); else if (dollars>=2) println("_Dollars")
var quarter = Math.floor(remChange1/0.25);
var remChange2 = remChange1-(quarter*0.25);
print(Math.round(quarter*4)/4)
if(quarter<2) println("_Quarter"); else if (quarter>=2) println("_Quarters")
var dime = Math.floor(remChange2 / 0.10);
var remChange3 = remChange2 - (dime*0.10);
print(Math.round(dime*10)/10)
if(dime<2) println("_Dime") else if(dime>=2) println("_Dimes")
var nickel = Math.floor(remChange3 / 0.05);
var remChange4 = remChange3 - (nickel*0.05);
print(Math.round(nickel*20)/20)
if(nickel<2) println("_Nickel") else if (nickel>=2) println("_Nickels")
var penny = Math.floor(remChange4*100);
print(Math.round(penny*100)/100)
if(penny<2) println("_Penny") else if (penny>=2) println("_Pennies")
return Unit;
}
here is my attempt at this:
fun main(args: Array<String>) {
val change = 10.88
Dollar(change);
Quarter(change);
Dime(change);
Nickel(change);
Penny(change);
}
fun Dollar(myChange: Double): Double{
val dollar = myChange/(1.00).toFloat();
val change1 = myChange - (dollar * 1.00);
print((dollar * 1)/1);
if(dollar<2) println("_Dollar"); else if (dollar>=2) println("_Dollars");
return change1
}
fun Quarter(myChange: Double): Double{
val quarter = myChange/(0.25).toFloat();
val change2 = myChange - (quarter * 0.25);
println((quarter*4)/4);
if(quarter<2) println("_Quarter"); else if (quarter>=2) println("_Quarters");
return change2
}
fun Dime(myChange: Double): Double{
val dime = myChange/(0.10).toFloat();
val change3 = myChange - (dime * 0.10);
println((dime * 10)/10);
if(dime<2) println("_Dime"); else if(dime>=2) println("_Dimes");
return change3
}
fun Nickel(myChange: Double): Double{
val nickel = myChange/(0.05).toFloat();
val change4 = myChange - (nickel * 0.05);
println((nickel*20)/20);
if(nickel<2) println("_Nickel"); else if (nickel>=2) println("_Nickels");
return change4
}
fun Penny(myChange: Double){
val penny = myChange/100);
print((penny * 100)/ 100);
if(penny<2) println("_Penny"); else if (penny>=2) println("_Pennies");
return Unit
}
OUTPUT:
Unexpected tokens (use ';' to separate expressions on the same line)
Expecting an element
I can't figure out where the rouge ';' is or lack there of
and I'm not sure why it's missing an element. I just want it to produce the same output as my first code. I've done everything from youtube, w3, chegg, online forum research.
Since this is homework I'm not just going to provide a solution, but here's something important to consider - usually, the point of breaking stuff down into multiple functions is to reduce repetition, and make code reusable by having it as its own function. Check this out, from your solution:
fun Dime(myChange: Double): Double{
val dime = myChange/(0.10).toFloat();
val change3 = myChange - (dime * 0.10);
println((dime * 10)/10);
if(dime<2) println("_Dime"); else if(dime>=2) println("_Dimes");
return change3
}
fun Nickel(myChange: Double): Double{
val nickel = myChange/(0.05).toFloat();
val change4 = myChange - (nickel * 0.05);
println((nickel*20)/20);
if(nickel<2) println("_Nickel"); else if (nickel>=2) println("_Nickels");
return change4
}
Obviously there's a lot of repetition there, which is probably part of the reason you're saying it's just making things harder - it's true, it is! It's bloating the code and making it harder to maintain, because any change in the logic has to be repeated for every function, because it's the same logic, just using different values.
So what you could do, is create one calculation function that handles this logic, using a set of values that's passed in. Then, each denomination's function can call that calculation one, passing in the set of values appropriate for that denomination. So they end up acting as helper functions, "configuring" the main one.
So now the question is, what are those parameters? What is it that changes in each of those functions, what are the things that vary, the variables? You should probably think about it yourself before you read the rest, but I see these:
the value you're dividing by to get a coin count (e.g. 0.05 for nickels)
the value you're multiplying by to get a money total, to work out how much change is remaining (e.g. 0.05 for nickels)
the value you're multiplying your coin total by in the println statement (e.g. 20 for nickels)
the value you're dividing by in the same statement (e.g. 20 for nickels)
singular and plural labels for the denomination (e.g. _Nickel and Nickels for nickels)
Some of those look the same (e.g. 0.05 and 0.05) so maybe you can pass in a single variable, which gets used in two places in the logic. You have to work out if this is the case, if they're the same value being referenced twice, or if it's a coincidence.
Some of those also look related to other values, e.g. 10 * 0.1 = 1.0, 20 * 0.05 = 1.0. If this is the case, and there's a consistent relationship between two values, then maybe you can derive one from the other, meaning you only need to pass one value in, and calculate the others you need to use from that. Again, you need to work out if this is logically sound - you're writing an algorithm here, you need to understand what those values are and what they mean. Breaking stuff down into reusable functions is all about this kind of generalisation and working out how things relate to each other.
Once you have your nice utility function that takes a set of parameters, you can make helper functions that call it with a fixed set of values:
fun nickels(myChange: Double): Double {
return calculate(parameters relating to nickels go here)
}
and now, there's no repetition! The calculation code is in one function, the printing code is in one function, and each of the denomination functions just holds unique data (the parameters passed to the main function).
I wouldn't necessarily tackle this problem like this (and I'm not reviewing the actual logic in your functions either) but it's good as a general example of how you approach things in a more functional way. Basically - if you find yourself repeating things, maybe you can stick that in its own function, and have the repeats call that instead
import kotlin.math.floor
fun dollars(remChange: Double): Double {
return arrayOf(1.0).fold(0.0 to remChange) { acc, dbl ->
val amount = floor(acc.second / dbl) * dbl
amount to acc.second - amount
}.first
}
fun quarters(remChange: Double): Double {
return arrayOf(1.0, 0.25).fold(0.0 to remChange) { acc, dbl ->
val amount = floor(acc.second / dbl) * dbl
amount to acc.second - amount
}.first
}
fun dimes(remChange: Double): Double {
return arrayOf(1.0, 0.25, 0.1).fold(0.0 to remChange) { acc, dbl ->
val amount = floor(acc.second / dbl) * dbl
amount to acc.second - amount
}.first
}
fun nickels(remChange: Double): Double {
return arrayOf(1.0, 0.25, 0.1, 0.05).fold(0.0 to remChange) { acc, dbl ->
val amount = floor(acc.second / dbl) * dbl
amount to acc.second - amount
}.first
}
fun pennies(remChange: Double): Double {
return arrayOf(1.0, 0.25, 0.1, 0.05, 0.01).fold(0.0 to remChange) { acc, dbl ->
val amount = floor(acc.second / dbl) * dbl
amount to acc.second - amount
}.first
}
val amount = 44.77
println("Dollars : " + dollars(amount)) // 44.0
println("Quarters : " + quarters(amount)) // 0.75
println("Dimes : " + dimes(amount)) // 0.0
println("Nickels : " + nickels(amount)) // 0.0
println("Pennies : " + pennies(amount)) // 0.2
Your error is this extra closing parenthesis on this line:
val penny = myChange/100);
I don't know of any online playground that shows you the error in the proper location. If you use an IDE like IntelliJ IDEA, it will highlight the error in your code as you type it with a red squiggly underline, just like a typo in a word processor. I highly recommend using IntelliJ IDEA if you are trying to learn Kotlin. It would have saved you a lot of time here.
Regarding your homework task, I think the point of challenging you to break your function up is to remove the repetition, which is a core principle of effective programming. Your new solution breaks it up into multiple functions without removing the repetition, so that's why it seems like a less sensible solution to you. See #cactustictacs' answer for more info about that.

Can someone explain this code for me? Base-Conversion Code

So for a homework assignment we had to make a program that converted a number from one base to another (i.e. 110 in base 2 to 6 in base 10). I asked my friend how he did his because I was having trouble and he just sent me his code and nothing else. Can someone explain the logic of this code so that I can make my own program and actually understand how to do this problem. Thanks!
import java.util.*;
public class Base_Converter {
public static final String value = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static void main(String args[]){
int x, y;
String num, base10 = "";
Scanner scan = new Scanner(System.in);
System.out.println("Enter a number you want to convert.");
num = scan.nextLine();
num = num.toUpperCase();
System.out.println("What base is it in?");
x = scan.nextInt();
System.out.println("What base do you want to convert it to?");
y = scan.nextInt();
if(x <= 36 && y <= 36 && x > 1 && y > 1){
base10 = toBase10(num,x);
num = newBase(base10,y);
System.out.println(num);
}
}
public static String toBase10(String num, int from){
long total = 0;
int counter = num.length();
char[] stringArray = num.toCharArray();
for(char w : stringArray){
counter--;
total += value.indexOf(w)*Math.pow(from,counter);
}
return String.valueOf(total);
}
public static String newBase(String num, int to){
String total = "";
int current = 0;
while(Integer.valueOf(num) > 0){
current = Integer.valueOf(num)%to;
total = value.charAt(current)+total;
num = String.valueOf(Integer.valueOf(num)/to);
}
return total;
}
}
I think you should be focusing not on what your friend's code does, but instead with how to do the assignment yourself, because I think your problems lie with a lack of understanding on your part. Instead of leaving you high and dry though I'll walk you through some of the specifics of base-conversion.
First, read user input. It looks like you're using Java, so just use a scanner to do this. At minimum you'll want to read the number you're converting, what base it is in, and what base the output will be in.
Next, we want to convert the number. You could directly convert numbers to each other (i.e. converting base 2 to base 8) but that requires more brainpower than I am willing to offer right now. Instead, I would suggest always first converting the user-inputted number to base 10 (much like your friend did). So how do we convert a number of an unknown base to base 10?
So let's break down how a number is represented: lets say we have the number 234 in base ten. This is equivalent to 4*10^0 + 3*10^1 + 2*10^2 or 4 + 30 + 200 = 234. You can use this same conversion for any other numbers. I.E. if the number is 1763 in base 8, the value in base 10 will be 3*8^0 + 6*8^1 + 7*8^2 + 1*8^3 or 3 + 48 + 448 + 512 = 1011 base 10(try entering 1763 here for proof. So to convert to decimal, you just need to see to multiply each individual number time your base to the power of its place minus 1. For example, since 1 is the fourth number in the 1763 you multiply it times 8^(4-1). Since, you are reading a string from the user. You'll need to convert each character of the string to an integer using the ascii chart.
Now to convert from base ten to anything. Instead of multiplying, you just divide each value and write the remainder! I'll let someone else describe this procedure.
Now just store this new value as a string doing somethings like
String output = "";
output += newValue;
In computer science, just copying someone else's code is way more harmful than helpful. Hope this helps!

Adding two numbers don't get correct result

I try to add two numbers, but don't get correct result
var n1:Number = 2785077255;
var n2:Number = 100000097214922752;
trace(Number(n1 + n2));//trace 100000100000000000, not 100000100000000007
trace((Number.MAX_VALUE - Number(n1 + n2)) > 100);//trace true
When I got the wrong result, I thought it exceed the Number's max value,so I test it and it doesn't trace false as I thought.
Yes, the problem is in Number as #Phylogenesis mentioned, it's actually 64 bit double with 52 bits for mantis, but your result exceededs that.
The good news are that there is a workaround for that, event two :)
Use some BigInteger/LongInt AS3 impelementation (you can google several of them), for instance BigInteger from as3crypto, or LongInt from lodgamebox
It's currently only for multiplying, but you can modify that solution as a small task. For best performance (without creation of temporary arrays/byte arrays) you can use that utility method that I created once (it's based on LongInt from lodgamebox library)
/**
* Safe multiplying of two 32 bits uint without precision lost.
*
* Usage:
* Default behaviour (with 64 bit Number mantis overflow):
* uint(1234567890 * 134775813) = 1878152736
*
* Fixed correct result by that method:
* uint(1234567890 * 134775813) = 1878152730
*
* #param val1
* #param val2
* #return
*
*/
public static function multiplyLong(val1:uint, val2:uint):uint
{
var resNum:Number = val1*val2;
//52 bits of mantis in 64 bit double (Number) without loose in precision
if(resNum <= 0xFFFFFFFFFFFFF)
return uint(resNum);
//count only low 32 bits of multiplying result
var i:uint, mul:Number, ln:uint=0, hn:uint=0, _low:uint = val1;
for (i = 1<<31; i; i >>>= 1)
{
if(val2 & i)
{
mul = _low * i;
ln += mul & uint.MAX_VALUE;
}
}
_low = ln;
return _low;
}

Reduce number of decimals

In AS3, from a division I get a number like this one: 0.9130406010219044.
Is there any way to reduce the number of decimals (aside from multiplying that number for one million)? Is there a way to reduce the numbers BEFORE the division is performed?
Got the following function from this link, which rounds to an arbitrary number of decimals:
public function trim(theNumber:Number, decPlaces:Number) : Number {
if (decPlaces >= 0) {
var temp:Number = Math.pow(10, decPlaces);
return Math.round(theNumber * temp) / temp;
}
return theNumber;
}
// Round a number to two decimal places trace(trim(1.12645, 2));
// Displays: 1.13
Note: I slightly changed the function definition by adding types. See the link for explanation and original source code. Also made it return theNumber if decPlaces is less than or equal to zero.
var myNumber:Number = 74.559832;
trace(myNumber.toFixed(4)); //74.5598
trace(myNumber.toFixed(2)); //74.56
AS3 Documentation: Number class
If you just want to display the result (you didn't specify) then a simple bit of String manipulation will yield the fastest result:
0.9130406010219044.toString().substr(0, 4); // 0.91
Take a look at NumberFormatter.fractionalDigits
Or, if you're working in Flex: mx:NumberFormatter.precision / s:NumberFormatter.fractionalDigits
Try some of the answers here on for size:
How to deal with Number precision in Actionscript?
If you use a NumberFormatter, make sure to specify rounding (it's most likely you'll want nearest).
If you need Number as result and performance, I would say this solution is more efficient than the Math.pow()
If you need 3 decimals just change 100 by 1000.
var myNumber:Number = 3.553366582;
myNumber = (( myNumber * 100 + 0.5) >> 0) / 100;
//trace = 3.55
demonstrating the rounding :
var myNumber:Number = 3.557366582;
myNumber = (( myNumber * 100 + 0.5) >> 0) / 100;
//trace = 3.56
Regarding the Number.toFixed() returning a String I guess it's because it returns 2 decimals in any case:
For instance :
Number(3).toFixed(2); // trace 3.00 so it has to be a String.

Howto convert decimal (xx.xx) to binary

This isn't necessarily a programming question but i'm sure you folks know how to do it. How would i convert floating point numbers into binary.
The number i am looking at is 27.625.
27 would be 11011, but what do i do with the .625?
On paper, a good algorithm to convert the fractional part of a decimal number is the "repeated multiplication by 2" algorithm (see details at http://www.exploringbinary.com/base-conversion-in-php-using-bcmath/, under the heading "dec2bin_f()"). For example, 0.8125 converts to binary as follows:
1. 0.8125 * 2 = 1.625
2. 0.625 * 2 = 1.25
3. 0.25 * 2 = 0.5
4. 0.5 * 2 = 1.0
The integer parts are stripped off and saved at each step, forming the binary result: 0.1101.
If you want a tool to do these kinds of conversions automatically, see my decimal/binary converter.
Assuming you are not thinking about inside a PC, just thinking about binary vs decimal as physically represented on a piece of paper:
You know .1 in binary should be .5 in decimal, so the .1's place is worth .5 (1/2)
the .01 is worth .25 (1/4) (half of the previous one)
the .001 is worth (1/8) (Half of 1/4)
Notice how the denominator is progressing just like the whole numbers to the left of the decimal do--standard ^2 pattern? The next should be 1/16...
So you start with your .625, is it higher than .5? Yes, so set the first bit and subtract the .5
.1 binary with a decimal remainder of .125
Now you have the next spot, it's worth .25dec, is that less than your current remainder of .125? No, so you don't have enough decimal "Money" to buy that second spot, it has to be a 0
.10 binary, still .125 remainder.
Now go to the third position, etc. (Hint: I don't think there will be too much etc.)
There are several different ways to encode a non-integral number in binary. By far the most common type are floating point representations, especially the one codified in IEEE 754.
the code works for me is as below , you can use this code to convert any type of dobule values:
private static String doubleToBinaryString( double n ) {
String val = Integer.toBinaryString((int)n)+"."; // Setting up string for result
String newN ="0" + (""+n).substring((""+n).indexOf("."));
n = Double.parseDouble(newN);
while ( n > 0 ) { // While the fraction is greater than zero (not equal or less than zero)
double r = n * 2; // Multiply current fraction (n) by 2
if( r >= 1 ) { // If the ones-place digit >= 1
val += "1"; // Concat a "1" to the end of the result string (val)
n = r - 1; // Remove the 1 from the current fraction (n)
}else{ // If the ones-place digit == 0
val += "0"; // Concat a "0" to the end of the result string (val)
n = r; // Set the current fraction (n) to the new fraction
}
}
return val; // return the string result with all appended binary values
}