-
Notifications
You must be signed in to change notification settings - Fork 7
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
Alternative to native representation of numbers #5
Comments
Hey Lukinoh, My apologies for the delayed response. I think this is totally possible. We'd basically have something like: export interface Quantity<V, D extends Dimensions> {
readonly amount: V;
// ...
} It would be super nice if we could just automatically support being able to write something like: const numberLength = meters(5);
const bigIntLength = meters(new BigInt('5'));
const decimalLength = meters(new Decimal('5')); The primary issue is that the different numeric types have different operators for the same arithmetic operation, so you need to tell the library somehow how to add, subtract, multiply and divide numbers. To be clear, I'm not worried about the extra computational overhead of introducing an indirection through a function call (any decent JS environment like V8 will optimize it by inlining anyways), it's more that I'm not sure what the right API is. Thinking out loud:
I kinda like variant 2, I'm mostly wondering about the right name for I also just realized that we could further simplify the quantity creation even further to avoid the annoying const decimalArithmetic: Arithmetic<Decimal, number|string> = {
create: (v: number|string) => new Decimal(v),
add: (a: Decimal, b: Decimal) => a.plus(b),
sub: (a: Decimal, b: Decimal) => a.minus(b),
};
const {meters} = withValueType(decimalArithmetic);
const decimalLength: Length = meters('5'); What do you think? |
Hello, I would probably go with the Variant 2 and the Concerning the naming of Just a side note. Before starting using your library, I was using another one that is not maintained anymore. |
Hello @buge , I am currently working on two implementations of the proposition. The first one is based on adding an arithmetic interface as proposed above. For instance: It is working, but I found the solution quite hard to read.
With this solution the calculus becomes more readable from my point of view. So I would like to know which solution you prefer. edit: I may have found a better compromise, I will try it when I have a bit of time |
Hello, NumberType + ArithemeticThis solution is based on the one you proposed. export interface Arithmetic<NumberType> {
fromNative(value: number): NumberType;
toNative(value: NumberType): number;
add(left: NumberType, right: NumberType): NumberType;
sub(left: NumberType, right: NumberType): NumberType;
mult(left: NumberType, right: NumberType): NumberType;
div(left: NumberType, right: NumberType): NumberType;
pow(base: NumberType, exponent: NumberType): NumberType;
abs(value: NumberType): NumberType;
} This is probably the simplest solution overall, however reading the calculation can become a bit cumbersome. WrappedNumberTypeThis solution will wrap the NumberType into another class that allows to do directly calculation export interface NumberWrapper<NumberType> {
add(value: NumberWrapper<NumberType>): NumberWrapper<NumberType>;
sub(value: NumberWrapper<NumberType>): NumberWrapper<NumberType>;
mul(value: NumberWrapper<NumberType>): NumberWrapper<NumberType>;
div(value: NumberWrapper<NumberType>): NumberWrapper<NumberType>;
pow(value: NumberWrapper<NumberType>): NumberWrapper<NumberType>;
abs(): NumberWrapper<NumberType>;
toNative(): number;
}
// from: number => NumberType
The calculation is more readable, but add complexity by wrapped the value into a class. NumberType with Builder-like ArithematicThis solution is a bit a mix of the both above. export interface Arithmetic<NumberType> {
add(value: NumberType): Arithmetic<NumberType>;
sub(value: NumberType): Arithmetic<NumberType>;
mul(value: NumberType): Arithmetic<NumberType>;
div(value: NumberType): Arithmetic<NumberType>;
pow(value: NumberType): Arithmetic<NumberType>;
abs(): Arithmetic<NumberType>;
val(): NumberType;
toNative(): number;
}
export interface ArithmeticFactory<NumberType> {
convert(value: number): NumberType;
from(value: number): Arithmetic<NumberType>;
from(value: NumberType): Arithmetic<NumberType>;
}
With this solution you are avoiding wrapping, but adding a bit of overhead to calculation. Which solution do you prefer ? Edit: I went for "NumberType + Arithemetic" at the end it is the best and more flexible. |
Hello,
It is not an issue, but a question.
As you may know, JavaScript and decimal it's not great love.
So if you do
0.1 + 0.2
the result will be0.30000000000000004
.Currently, in your library you are using native representation of numbers, so such issue could arise (which is fine me).
However, there is no easy way to replace the default behaviour. So I had to duplicate the
unit.ts
and adapt it to use decimal.js.Do you plan to offer a way to have better integration with libraries such as
decimal.js
?P.S. Don't hesitate to edit the title of the issue.
The text was updated successfully, but these errors were encountered: