Using the rust crate uom, how do I raise a quantity as a power of the dimensionless quantity e?
use uom::si::f32::*;
use uom::si::length::kilometer;
fn main() {
let length = Length::new::<kilometer>(5.0);
let answer = std::f32::consts::E.pow(length); // doesn't compile
}
Related
My code works in a file by itself but whenever I try to run the Rustlings quiz1.rs there is an error in the testing part of the code.
// GOAL OF PROGRAM
// Mary is buying apples. One apple usually costs 2 Rustbucks, but if you buy
// more than 40 at once, each apple only costs 1! Write a function that calculates
// the price of an order of apples given the order amount. No hints this time
fn calculate_apple_price(apples: i32){
let mut price = 2;
if apples >= 40 {
price = 1;
}
}
// Don't modify this function!
#[test]
fn verify_test() {
let price1 = calculate_apple_price(35);
let price2 = calculate_apple_price(65);
assert_eq!(70, price1); // Error happens here 'no implementation for `{integer} == ()`'
assert_eq!(65, price2);// Error happens here 'no implementation for `{integer} == ()`'
}
I googled the problem and tried rust explain, but i am new to Rust. Can someone explain this error in plain english?
You forgot to specify a return type to fn calculate_apple_price, price1 and price2 are filled with a zero-sized type (this can be confusing when your learning RUST).
You should try something like this
fn calculate_apple_price(apples: i32) -> i32 /* specify i32 as return type */ {
let mut price = 2;
if apples >= 40 {
price = 1;
}
price // Return the price (the `return` keyword is optional in this case)
}
Obviously accepted answer is wrong.
Correct one:
fn calculate_apple_price(n:i32)-> i32 {
if n > 40 {
n
}else{
n * 2
}
}
I was making the original functionality wrong. I was returning what the price of one apple would be for whatever amount. Instead I was supposed to return the final price of all apples. here is the function for that
fn calculate_apple_price(apples: i32) -> i32{
let mut price = 0;
if apples <= 40 {
price = apples * 2
} else {
price = apples * 1
}
price
}
I'm trying to implement a function:
extern crate num_bigint as bigint;
use bigint::{BigUint};
fn encode(bytes: BigUint) -> Vec<char> {
// determine padding length
let num_bits = bytes.bits();
let padding: bool = num_bits % 6 != 0;
let num_chars: usize = num_bits / 6;
let bitmask = BigUint::parse_bytes(b"7", 16);
let mut base64_chars: Vec<char> = Vec::new();
for idx in num_chars..0 {
let shifted = bytes << (num_chars * 6);
use BigUint;
let c = shifted.to_u8();
}
return base64_chars;
}
it fails on let c = shifted.to_u8()
no method named to_u8 found for type bigint::BigUint in the current scope.
method not found in bigint::BigUint.
help: items from traits can only be used if the trait is in scope
Coming from a c++ background I'm having more of a struggle with learning Rust than I expected. What is that help text trying to let me know? I tried adding using BigUint before the line, but that just states I'm doing something redundant. How do I get to use this trait?
From #Frxstrem's helpful comment!
Importing the crate num-traits and doing the following fixed this:
use num_traits::cast::ToPrimitive;
let c = shifted.to_u8();
In Java, intValue() gives back a truncated portion of the BigInteger instance. I wrote a similar program in Rust but it appears not to truncate:
extern crate num;
use num::bigint::{BigInt, RandBigInt};
use num::ToPrimitive;
fn main() {
println!("Hello, world!");
truncate_num(
BigInt::parse_bytes(b"423445324324324324234324", 10).unwrap(),
BigInt::parse_bytes(b"22447", 10).unwrap(),
);
}
fn truncate_num(num1: BigInt, num2: BigInt) -> i32 {
println!("Truncation of {} is {:?}.", num1, num1.to_i32());
println!("Truncation of {} is {:?}.", num2, num2.to_i32());
return 0;
}
The output I get from this is
Hello, world!
Truncation of 423445324324324324234324 is None.
Truncation of 22447 is Some(22447).
How can I achieve this in Rust? Should I try a conversion to String and then truncate manually? This would be my last resort.
Java's intValue() returns the lowest 32 bits of the integer. This could be done by a bitwise-AND operation x & 0xffffffff. A BigInt in Rust doesn't support bitwise manipulation, but you could first convert it to a BigUint which supports such operations.
fn truncate_biguint_to_u32(a: &BigUint) -> u32 {
use std::u32;
let mask = BigUint::from(u32::MAX);
(a & mask).to_u32().unwrap()
}
Converting BigInt to BigUint will be successful only when it is not negative. If the BigInt is negative (-x), we could find the lowest 32 bits of its absolute value (x), then negate the result.
fn truncate_bigint_to_u32(a: &BigInt) -> u32 {
use num_traits::Signed;
let was_negative = a.is_negative();
let abs = a.abs().to_biguint().unwrap();
let mut truncated = truncate_biguint_to_u32(&abs);
if was_negative {
truncated.wrapping_neg()
} else {
truncated
}
}
Demo
You may use truncate_bigint_to_u32(a) as i32 if you need a signed number.
There is also a to_signed_bytes_le() method with which you could extract the bytes and decode that into a primitive integer directly:
fn truncate_bigint_to_u32_slow(a: &BigInt) -> u32 {
let mut bytes = a.to_signed_bytes_le();
bytes.resize(4, 0);
bytes[0] as u32 | (bytes[1] as u32) << 8 | (bytes[2] as u32) << 16 | (bytes[3] as u32) << 24
}
This method is extremely slow compared to the above methods and I don't recommend using it.
There's no natural truncation of a big integer into a smaller one. Either it fits or you have to decide what value you want.
You could do this:
println!("Truncation of {} is {:?}.", num1, num1.to_i32().unwrap_or(-1));
or
println!("Truncation of {} is {:?}.", num1, num1.to_i32().unwrap_or(std::i32::MAX));
but your application logic should probably dictate what's the desired behavior when the returned option contains no value.
I'm just learning rust, henceforth this question has probably some trivial answer.
I want to access to individual digits of a rust BigUint. This is for a project Euler puzzle asking the sum of these digits.
I did it like below:
let mut f = func(100);
let mut total: BigUint = Zero::zero();
while f > FromPrimitive::from_uint(0).unwrap() {
let digit = f % FromPrimitive::from_uint(10).unwrap();
f = f / FromPrimitive::from_uint(10).unwrap();
total = total + digit;
}
println!("");
println!("Sum of digits of func(100) = {}", total);
It works, but it's quite frustrating, because I believe these digits are internaly stored as an array, but I can't access to them directly because the underlying data member is private.
Is there any way to do that in a more straightforward way ?
The internal storage of BigUint is a vector of BigDigit, which is an alias for u32, so it probably won't help you a lot to get the sum of base 10 digits.
I doubt casting to String would be an efficient way to compute this, but you can make it a little more straightforward using the div_rem() method from trait Integer. (After all, casting to String does this computation internally.)
extern crate num;
use std::num::Zero;
use num::bigint::BigUint;
use num::integer::Integer;
fn main() {
let mut f = func(100);
let mut total: BigUint = Zero::zero();
let ten: BigUint = FromPrimitive::from_uint(10).unwrap();
while f > Zero::zero() {
let (quotient, remainder) = f.div_rem(&ten);
f = quotient;
total = total + remainder;
}
println!("");
println!("Sum of digits of func(100) = {}", total);
}
I ended doing it using to_string() as suggested by #C.Quilley. But as #Levans pointed out the internal implementation merely perform a div_rem. I still prefer that version because I see it as more readable and straightforwad.
extern crate num;
use num::bigint::BigUint;
// What this function does is irrelevant
fn func(n: uint) -> BigUint {
let p : BigUint = FromPrimitive::from_uint(n).unwrap();
p*p*p*p*p*p*p*p*p*p*p*p*p
}
fn main() {
let n = 2014u;
let f = func(n);
let total: uint = f.to_string().as_slice().chars()
.fold(0, |a, b| a + b as uint - '0' as uint);
println!("Sum of digits of func({}) = {} : {}", n, f, total);
}
Editor's note: This question's example is from a version of Rust prior to 1.0 and references types and methods no longer found in Rust. The answers still contain valuable information.
The following code
let mut numbers = new_serial.as_bytes().iter().map(|&x| (x - 48));
let sum = numbers.sum();
results in the following error:
std::iter::Map<,&u8,u8,std::slice::Items<,u8>>` does not implement any method in scope named `sum`
What must I do to sum an array of bytes?
The following works:
for byte in new_serial.as_bytes().iter() {
sum = sum + (byte - 48);
}
Iterator::sum was stabilized in Rust 1.11.0. You can get an iterator from your array/slice/Vec and then use sum:
fn main() {
let a = [1, 2, 3, 4, 5];
let sum: u8 = a.iter().sum();
println!("the total sum is: {}", sum);
}
Of special note is that you need to specify the type to sum into (sum: u8) as the method allows for multiple implementations. See Why can't Rust infer the resulting type of Iterator::sum? for more information.
Applied to your original example:
let new_serial = "01234";
let sum: u8 = new_serial.as_bytes().iter().map(|&x| x - 48).sum();
println!("{}", sum);
As an aside, it's likely more clear if you use b'0' instead of 48.
If performance is important, consider using an implementation that helps the compiler at producing SIMD instructions.
For example, for f32, using 16 lanes (total of 512 bits):
use std::convert::TryInto;
const LANES: usize = 16;
pub fn nonsimd_sum(values: &[f32]) -> f32 {
let chunks = values.chunks_exact(LANES);
let remainder = chunks.remainder();
let sum = chunks.fold([0.0f32; LANES], |mut acc, chunk| {
let chunk: [f32; LANES] = chunk.try_into().unwrap();
for i in 0..LANES {
acc[i] += chunk[i];
}
acc
});
let remainder: f32 = remainder.iter().copied().sum();
let mut reduced = 0.0f32;
for i in 0..LANES {
reduced += sum[i];
}
reduced + remainder
}
pub fn naive_sum(values: &[f32]) -> f32 {
values.iter().sum()
}
for
let values = (0..513).map(|x| x as f32).collect::<Vec<_>>();
the above is 10x faster than values.iter().sum() on my computer:
nonsimd_sum time: [77.341 ns 77.773 ns 78.378 ns]
naive_sum time: [739.97 ns 740.48 ns 740.97 ns]
and ~10% slower than using packed_simd2 (but it does not require nightly).