public class Book implements Serializable {
private static final long serialVersionUID = -1442621618;
private Integer id;
private String title;
private Float price;
public Book() {}
}
shared class Book(title, price) {
late shared Integer id;
shared String title;
shared Float price;
print("Price::::======``price``");
shared actual Boolean equals(Object that) {
if (is Book that) {
return title==that.title;
}
else {
return false;
}
}
shared actual Integer hash {
variable value hash = 1;
hash = 31*hash + title.hash;
return hash;
}
string => "[Book:``id``->``title``::``price``]";
}
Now I'm converting the database object which is a Java object into the ceylon object using the following adapter
function convertToBook(DbBook dbBook) {
value book = Book(dbBook.title, FloatConverter().from(dbBook.price));
book.id = IntegerConverter().from(dbBook.id);
return book;
}And the FloatConverter is simply converting Java Float to Ceylon Float no additional information gets added while doing the conversion.shared class FloatConverter() satisfies Converter<JFloat,Float> {
shared actual Float from(JFloat t) => t.floatValue();
shared actual Clazz<JFloat> fromType() => javaClass<JFloat>();
shared actual JFloat? to(Float? u) => if(exists u) then JFloat(u) else null;
shared actual Clazz<Float> toType() => javaClass<Float>();
}But when the Book(title, price) constructor is invoked by the convertToBook() method the constructor adds additional decimal places to price field as below:10:10:00,960 INFO [stdout] (default task-1) Price::::======45.9900016784668 10:10:00,961 INFO [stdout] (default task-1) Price::::======45.9900016784668 10:10:00,961 INFO [stdout] (default task-1) Price::::======17.989999771118164 10:10:00,961 INFO [stdout] (default task-1) Price::::======33.9900016784668
Why is Ceylon adding additional decimal places and is there a way to get around it?
float f=0.99;
double d=f;
System.out.println(d);
Anyway for something like price in Java usually BigDecimal is recommended.
import java.lang {JFloat=Float,Double}shared void run(){print(Float(JFloat(49.99).floatValue()));print(Float(Double(49.99).doubleValue()));print(Float(49.99));}Output:49.990001678466849.9949.99Java Double gets converted to Ceylon Float without additional precision values, whereas during Java Float to Ceylon Float conversion, additional precision values gets added.I was expecting the results to be vice-versa. :)