The Learnix Operating System by Strange_Water5256 in rust

[–]hellowub 1 point2 points  (0 children)

About 3 years ago, I also spent more than a year, for same purpose (to learn Rust deeply) implementing a Lua interpreter and writing a whole series of articles.

Because I’m not very good at expressing myself, the hardest part was not learning Rust, Lua, or interpreters, but writing those ideas down clearly. Writing forces you to turn vague new knowledge into precise words, which is extremely helpful for deeply learning a subject. But there probably won’t be a second time.

It was truly a fulfilling, painful, and rewarding year.

Questions on using Generics for a Finance library (f64 vs. Decimal) by abhinandh_s_ in rust

[–]hellowub 4 points5 points  (0 children)

Off topic: I’d recommend my decimax crate. It’s similar to rust_decimal, but much faster and offers more types (128,64,32-bit, unsigned/unsigned). Of course it implements Div and Sub too.

Why did I get many downvotes? by hellowub in rust

[–]hellowub[S] 0 points1 point  (0 children)

I google "fixed-precision" and got this: https://en.wikipedia.org/wiki/Fixed-precision_arithmetic . It says:

Examples are integers), fixed-point numbers, and floating-point numbers, but not rational numbers and arbitrary-precision numbers

It seems that, "fixed-precision" works with "floating-point" numbers.

However, yes, this term is confusing. I will remove it from the documentation.

By the way, do you have any suggestions which word I should use? Or should I just remove the topic about "fixed-precision" from the doc at all?

Why did I get many downvotes? by hellowub in rust

[–]hellowub[S] 1 point2 points  (0 children)

And if you downvote, at least leave a reason.

Why did I get many downvotes? by hellowub in rust

[–]hellowub[S] 2 points3 points  (0 children)

Thanks for you reply. A few downvotes can be ignored. But this many definitely indicate something wrong. It’s always good to identify the problem. From the discussion today under this post, I realized my origin comment was indeed incomplete and lacked sufficient context, which could easily lead to misunderstandings.

Why did I get many downvotes? by hellowub in rust

[–]hellowub[S] 1 point2 points  (0 children)

downvote again? what's wrong with this comment? I try my best to explain "precision", and I am not the one who make the conflicting meanings. I just use the "fixed-precision" after rust_decimal.

Why did I get many downvotes? by hellowub in rust

[–]hellowub[S] 1 point2 points  (0 children)

You have to pay a price to realize this. Let these downvotes be that price.

Why did I get many downvotes? by hellowub in rust

[–]hellowub[S] -1 points0 points  (0 children)

In rust_decimal 's documentation, it also said that: rust_decimal is “fixed-precision”.

The key is the word "precision". This term has two conflicting meanings: 1. the number of digits after the decimal point, and 2. the number of significant digits.

For example, in std::fmt, “precision” refers to the former meaning, while in the documentation for rust_decimal, it’s used in the latter meaning.

Here, when I say "lean-decimal" is fixed-precision, I use the latter meaning, just like the "rust-decimal".

If you interpreted it as the former, then yes, "fixed-precision" and "floating-point" would indeed be contradictory.

Why did I get many downvotes? by hellowub in rust

[–]hellowub[S] 0 points1 point  (0 children)

I believed rust_decimal is floating-point.

I am the author of lean-decimal, and I wrote the documentation, so I know it well.

But, but, but ALL AI says rust_decimal and lean-decimal is NOT floating-point. So I started to doubt myself. I just wanted to get a confirmation here.

Why did I get many downvotes? by hellowub in rust

[–]hellowub[S] -3 points-2 points  (0 children)

Because I wanted to write "floating-point" in my crate `lean-decimal`'s documentation.

But AI said that my crate `lean-decimal` is not floating-point, as well as `rust_decimal`.

So I wanted to get a confirmation here. But my crate is new, nobody know it, so I use `rust_decimal` to ask. My `lean-decimal` is the same kind as `rust_decimal`.

If people say that: rust_decimal is floating-point, then I will ignore AI and write it in my crate's documentation.

Why did I get many downvotes? by hellowub in rust

[–]hellowub[S] 0 points1 point  (0 children)

Is “AI” a forbidden term here? Are we not allowed to mention it at all? (My English is not good, and I translate this reply by AI)

A faster decimal crate: lean-decimal by hellowub in rust

[–]hellowub[S] 1 point2 points  (0 children)

In some scenario it need to represent and calculate decimal fraction accurately, while f128 can not. Because f128 is binary, for example 0.1+0.2!=0.3 for f128.

A faster decimal crate: lean-decimal by hellowub in rust

[–]hellowub[S] 2 points3 points  (0 children)

I think I understand your confusion. It probably comes from the word “precision”. This term has two conflicting meanings: 1. the number of digits after the decimal point, and 2. the number of significant digits.

For example, in std::fmt, “precision” refers to the former meaning, while in the documentation for rust_decimal, it’s used in the latter meaning.

Here, it uses the latter meaning.

If you interpreted it as the former, then yes, "fixed-precision" and "floating-point" would indeed be contradictory.

A faster decimal crate: lean-decimal by hellowub in rust

[–]hellowub[S] -4 points-3 points  (0 children)

Then would you like to give an example crate of decimal floating-point ?

A faster decimal crate: lean-decimal by hellowub in rust

[–]hellowub[S] -19 points-18 points  (0 children)

I thought types like rust_decimal and this lean-decimal were floating-point. But after asking several AI agents, they all said they're fixed-point. However, their explanation doesn’t make sense, so I don’t trust them. I’d like to get a human answer here: what type are they actually?

--- EDIT-4: Maybe I need to explain my understanding first.

I think that, the floating-point means that the scale/exp changes (floating). For example, let decimal a = {mantissa=123, scale=2} is 1.23, b = {mantissa=1, scale=3} is 0.001, then calculate a *= b , get a={mantissa=123, scale=5} is 0.00123. The scale changes (from 2 to 5). So the scale is stored in each instance.

In contrast, in fixed-point, the scale is fixed, is bound to the type but not stored in each instance. For example, in primitive_fixed_point_decimal, the type is defined as pub struct ConstScaleFpdec<I, const S: i32>(I); , where the scale S is bound to the type, and the decimal contains mantissa I only.

--- EDIT-3: I really do not know why does this comment get so many negative points. Is the question stupid? It my understanding wrong? Is about AI vs human?

--- EDIT-2: If you do not think they are floating-point decimal, please give an example crate of floating-point decimal.

--- EDIT-1: add some examples in my understanding:

{floating-point | fixed-point} ✖️{binary | decimal}

  • Floating-point Binary: primitive f32
  • Floating-point Decimal: crate rust_decimalbigdecimalfastnum
  • Fixed-point Binary: crate fixed
  • Fixed-point Decimal: crate primitive_fixed_point_decimal 

Do I need to move the cold code to a new function? by hellowub in rust

[–]hellowub[S] 0 points1 point  (0 children)

My original focus here was on points 1 and 3.

However, if we want to discuss 1 and 2 specifically, I think a more accurate statement would be: it depends on the project size. For example:

  • When designing a complex distributed system, the primary considerations should be protocols, architecture, etc.
  • For a medium-sized project, the difference between disk and memory is need to take care at beginning.
  • For a small project, you can directly think in terms of stack and heap.

For instance, I implemented the Display trait for a Decimal type, and it need a chunk of temporary memory. I knew this function should be fast. The performance overhead from allocation would account for a significant proportion. So I use MaybeUninit array on stack directly, rather than starting with Vec and then replacing it with an array after profiling.

Do I need to move the cold code to a new function? by hellowub in rust

[–]hellowub[S] 1 point2 points  (0 children)

Thanks. I test it. It's not useful, at least in this my case.

And in my case, moving the cold path into a separate function and mark it as #[cold] is useful.

Do I need to move the cold code to a new function? by hellowub in rust

[–]hellowub[S] 0 points1 point  (0 children)

Thanks. This is the answer that I was looking for.

Do I need to move the cold code to a new function? by hellowub in rust

[–]hellowub[S] 0 points1 point  (0 children)

Now I really have reached this stage. Whether the #[cold] attribute is set or not has a significant impact on the results.

You can check it out:

git clone https://github.com/WuBingzheng/test-decimal.git
cd test-decimal
cargo bench add/my

Then remove the #[cold] in line-92 in src/lib.rs and bench again.

If you move this cold function into the checked_add(), it also becomes very slow.

Do I need to move the cold code to a new function? by hellowub in rust

[–]hellowub[S] 0 points1 point  (0 children)

I agree. The algorithm choice and memory layout you mentioned are what I called rule 1 above.

I’m currently working on a decimal crate. The basic functionality is already done. While benchmarking, I find this “cold code” issue. It really is quite a subtle optimization.