added basic fixed point

This commit is contained in:
Sven Vogel 2023-04-23 21:05:02 +02:00
parent 952185e1ef
commit 971906593d
8 changed files with 141 additions and 0 deletions

6
.gitignore vendored
View File

@ -14,3 +14,9 @@ Cargo.lock
# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb
# Added by cargo
/target
/Cargo.lock

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

6
.idea/misc.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/staticdot.iml" filepath="$PROJECT_DIR$/.idea/staticdot.iml" />
</modules>
</component>
</project>

12
.idea/staticdot.iml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

8
Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "staticdot"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

87
src/lib.rs Normal file
View File

@ -0,0 +1,87 @@
use std::ops;
use std::ops::{Add, BitAnd, Div, Mul, Shl, Shr, Sub};
const INTEGER_BITS: i32 = 8;
const FRACTION_BITS: i32 = 24;
/// in oder to create the fraction bits mask we first fill all bits with 1 by initializing it with -1
/// then we reinterpret the -1 as unsigned and shift it to the left. We need to do this in order to
/// avoid arithmetic shifts
const FRACTION_MASK: i32 = (-1i32 as u32 >> INTEGER_BITS) as i32;
#[derive(Copy, Clone)]
pub struct Fixed32(i32);
impl From<i32> for Fixed32 {
fn from(value: i32) -> Self {
Fixed32(value.shl(FRACTION_BITS))
}
}
impl From<f32> for Fixed32 {
fn from(value: f32) -> Self {
let integral = (value as i32).shl(FRACTION_BITS);
let fraction = (value.fract() * 1.shl(FRACTION_BITS) as f32) as i32;
Fixed32(integral | fraction)
}
}
impl Into<i32> for Fixed32 {
fn into(self) -> i32 {
self.0.shr(FRACTION_BITS)
}
}
impl Into<f32> for Fixed32 {
fn into(self) -> f32 {
let integral = self.0.shr(FRACTION_BITS) as f32;
let fraction = self.0.bitand(FRACTION_MASK) as f32 / 1.shl(FRACTION_BITS) as f32;
integral + fraction
}
}
impl Add<Fixed32> for Fixed32 {
type Output = Fixed32;
fn add(self, rhs: Fixed32) -> Self::Output {
Fixed32(self.0 + rhs.0)
}
}
impl Sub<Fixed32> for Fixed32 {
type Output = Fixed32;
fn sub(self, rhs: Fixed32) -> Self::Output {
Fixed32(self.0 - rhs.0)
}
}
impl Mul<Fixed32> for Fixed32 {
type Output = Fixed32;
fn mul(self, rhs: Fixed32) -> Self::Output {
Fixed32(self.0.shr(FRACTION_BITS / 2) * rhs.0.shr(FRACTION_BITS / 2))
}
}
impl Div<Fixed32> for Fixed32 {
type Output = Fixed32;
fn div(self, rhs: Fixed32) -> Self::Output {
Fixed32((self.0 / rhs.0.shr(FRACTION_BITS / 2)).shl(FRACTION_BITS / 2))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
let a = Fixed32::from(9);
let b = Fixed32::from(3);
let c = a * a / b;
println!("{}", Into::<f32>::into(c));
}
}