-
Notifications
You must be signed in to change notification settings - Fork 37
Allow non-float types #12
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
Conversation
5aa5300 to
01c2cae
Compare
Motivation:I am considering using this in a microcontroller where integers would be preferred over float due to hardware and performance limitations. This change enables me to pick any (signed) numeric type i could possibly want. NoteWhen using integers or similar, make sure to pick a large enough type as to avoid overflow in any of the multiplications in the |
Owez
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR, this is a really good feature to have. A few minor changes and I think it's ready to go
Ideally having tiny types which will cause UB will give a compiler error, but if not it needs to be documented somewhere eventually. Would one of the |
|
num_traits::Saturating and num_traits::SaturatingMul does seem like they would be nice for that, however that is only implemented for integers. Not sure if there is any way to work around that? |
|
I guess we could define trait Number: PartialOrd + num_traits::Signed + Copy {
fn safe_mul(self, other: Self) -> Self;
fn safe_add(self, other: Self) -> Self;
}and only implement However this would make it harder to use 3rd party types |
|
I guess something similar could be done for |
Theres OverflowingMul which looks to be implemented for for all types which can be used as a workaround, though having an I'll add some docs about it in the controller somewhere for small types |
I've implemented a version of this locally but I'm not sure what to do with the pub trait Number: PartialOrd + num_traits::Num + Copy {
/// Makes the value negative (`-value`) if signed, otherwise leaves it as `0`
fn neg_or_zero(val: Self) -> Self { Self::zero() }
}
impl Number for f64 { fn neg_or_zero(val: Self) -> Self { -val } }
impl Number for f32 { fn neg_or_zero(val: Self) -> Self { -val } }
impl Number for i128 { fn neg_or_zero(val: Self) -> Self { -val } }
impl Number for i64 { fn neg_or_zero(val: Self) -> Self { -val } }
impl Number for i32 { fn neg_or_zero(val: Self) -> Self { -val } }
impl Number for i16 { fn neg_or_zero(val: Self) -> Self { -val } }
impl Number for i8 { fn neg_or_zero(val: Self) -> Self { -val }}
impl Number for isize { fn neg_or_zero(val: Self) -> Self { -val } }
impl Number for u128 { }
impl Number for u64 { }
impl Number for u32 { }
impl Number for u16 { }
impl Number for u8 { }
impl Number for usize { } |
Oh, right... I guess that would sort of need to be signed? |
Googled quickly and looks like it can be done: https://ledin.com/integer-algorithms-implementation-and-issues/ |
|
Looks like |
This commit relaxes the bounds of the generics used for the controller so signed integers (e.g. i8, i64, etc.) can be used as well as floats. This has been done by adding a new trait which also allows user-defined numbers to be easily implemented. Resolves: braincore#12
e571e6f to
f0e6cf2
Compare
|
@braincore I've squashed here following https://medium.com/singlestone/a-git-workflow-using-rebase-1b1210de83e5. Want me to do a plain merge or rebase again onto master? |
|
I am using an ESP32 with esp-idf-hal. Quite nice actually, I really like the concept of having peripherals being objects ties into rusts ownership system. Making it impossible to use the same hardware resources for different things by accident. Other than that there have been some surprises, in the esp-idf-hal case, things like floats. There is hardware support for float in the mcu, however you can not use them from interrupts since those registers are not saved. That crash did take quite some time to figure out(I should have read the doc more closely :) ). I guess that is something which would be nice if the compiler could somehow magically tell me about... There is also the story about doc, at least as of right now esp-idf-hal is not that well documented so you have to read the corresponding C doc and/or try to find some example to know what to do. However I have been met by a great community that is very happy to answer my esp related questions and help me out. Anyways compared to C, it's great. Not having to turn your entire codbase upside down just because you forgot to put So in summary I think there are some great things and some less then great things. However overall the good does, in my mind, overweight the less good. I believe most of the bad things are planned/being worked on. |
|
@usbalbin Thanks for the rundown. I published an assortment of hardware peripheral crates for rust, but they were always used on a Raspberry Pi via i2c since the embedded story was rough at the time. It's great to hear that it's workable these days. Checking whether the FPU functions inside an interrupt is not exactly something that would have been on the top of my list either :). |
Relax trait bounds to allow types other than float
This allows using types like i8, i32 etc. or any other user type that satisfies
Debug + PartialOrd + num_traits::Signed + Copy