Question
How do you calculate an absolute value in Rust? Older documentation shows a function named std::num::abs, but calling it as num::abs(value) produces an unresolved-name error. What is the correct modern Rust syntax, and why does the older documentation differ?
Short Answer
Rust calculates absolute values with the .abs() method on numeric values rather than a general std::num::abs(...) function. You will learn the syntax for integers and floating-point numbers, the special overflow case for minimum signed integers, and safer alternatives when that case matters.
Concept
Rust's numeric types provide methods for operations that belong to a value. Absolute value is one of them.
For a signed number, use .abs():
let value: i32 = -42;
let positive = value.abs();
assert_eq!(positive, 42);
This is different from calling a namespaced free function such as num::abs(value). In modern Rust, there is no general std::num::abs function to import and call that way.
The older documentation in the question was for a very old Rust release. Rust's standard-library API changed substantially before Rust 1.0, so old versioned documentation does not necessarily match a current compiler. Always prefer the documentation for the Rust version you are using, especially the official current docs at doc.rust-lang.org.
Absolute value is common when computing distances, differences, magnitudes, or display-friendly values. The important detail is that it is available only where the numeric type can meaningfully support it: signed integers and floating-point types.
Mental Model
Think of a negative sign as an arrow pointing left on a number line. Absolute value asks only, "How far is this number from zero?" It ignores the arrow's direction.
In Rust, .abs() is like asking the number directly for that distance:
let temperature = -8;
let distance_from_zero = temperature.abs();
Instead of looking for a tool in a global num toolbox, you send a message to the value itself: "give me your absolute value."
Syntax and Examples
Use .abs() after a signed integer or floating-point value.
let debt: i32 = -125;
let amount_owed = debt.abs();
let offset: f64 = -3.75;
let distance = offset.abs();
assert_eq!(amount_owed, 125);
assert_eq!(distance, 3.75);
The type annotation on debt is useful because integer literals can otherwise be inferred as different integer types depending on context.
You can also call the method on an expression:
let first = 10;
let second = 27;
let difference = (first - second).abs();
assert_eq!(difference, 17);
The parentheses matter: Rust first calculates first - second, then calls .abs() on the result.
Unsigned integers such as u32 do not have negative values, so they do not need an absolute-value operation:
let count: u32 = 12;
// count.abs(); // Not available: count is already never negative.
Step by Step Execution
Consider this example:
let start: i32 = 18;
let end: i32 = 7;
let signed_change = end - start;
let distance = signed_change.abs();
assert_eq!(signed_change, -11);
assert_eq!(distance, 11);
Step by step:
startstores18andendstores7.end - startevaluates to7 - 18, which is-11.signed_changetherefore contains-11.signed_change.abs()removes the sign and produces11.- The final assertion confirms that the distance between the two values is
11regardless of direction.
Real World Use Cases
Absolute value is useful whenever the size of a difference matters more than its direction.
- Coordinates and movement: find how far a player moved on one axis:
(new_x - old_x).abs(). - Price or sensor tolerance: check whether a reading differs from an expected value by more than a permitted amount.
- Time offsets: display an elapsed offset without showing whether an event was early or late.
- Data validation: reject values whose deviation from a target is too large.
- Signals and audio: work with a sample's magnitude rather than whether the waveform is above or below zero.
For example, a tolerance check can be written as:
let expected: f64 = 20.0;
let measured: f64 = 20.3;
let tolerance: f64 = 0.5;
let is_close = (measured - expected).abs() <= tolerance;
assert!(is_close);
Real Codebase Usage
In real Rust code, .abs() is often used inside validation and comparison logic.
Tolerance checks
For floating-point values, direct equality is often inappropriate because calculations can contain small rounding differences. Compare the absolute difference instead:
fn approximately_equal(a: f64, b: f64, epsilon: f64) -> bool {
(a - b).abs() <= epsilon
}
assert!(approximately_equal(0.1 + 0.2, 0.3, 1e-10));
Guard clauses
A guard clause can reject invalid input early:
fn within_limit(change: i32, limit: i32) -> bool {
if change.abs() > limit {
return false;
}
true
}
Choosing an overflow policy
When code may receive the minimum value of a signed integer, developers make the behavior explicit rather than assuming .abs() always produces a positive signed integer:
let value = i32::MIN;
let magnitude: u32 = value.unsigned_abs();
assert_eq!(magnitude, 2_147_483_648);
unsigned_abs() is especially suitable when the result represents a non-negative magnitude.
Common Mistakes
Calling an obsolete free function
This syntax comes from obsolete Rust documentation and does not work in modern Rust:
// use std::num;
// let x = num::abs(value); // Error: no such function
Use the method on the value instead:
let x = value.abs();
Calling .abs() on an unsigned integer
Unsigned types cannot be negative, so .abs() is unnecessary and unavailable.
let value: u32 = 5;
// let result = value.abs(); // Does not compile
If a calculation might become negative, use a signed type for the calculation or use a method designed for unsigned differences, such as abs_diff.
Forgetting the minimum-integer edge case
Every signed integer type has one more negative value than positive values. For i32, i32::MIN is -2_147_483_648, but positive 2_147_483_648 cannot fit in an i32.
let minimum = i32::MIN;
// minimum.abs(); // Panics in debug builds; do not rely on it for this input
Choose an explicit alternative such as unsigned_abs(), checked_abs(), saturating_abs(), or wrapping_abs() based on the required behavior.
Using direct float equality
This is often fragile after arithmetic:
let equal = 0.1_f64 + 0.2_f64 == 0.3_f64;
Prefer an absolute-difference tolerance:
let equal = (0.1_f64 + 0.2_f64 - 0.3_f64).abs() < 1e-10;
Comparisons
| Need | Recommended Rust operation | Result behavior |
|---|---|---|
Normal absolute value of i32, i64, f32, or f64 | value.abs() | Returns the ordinary absolute value; signed integer minimum is exceptional |
| Magnitude of a signed integer, including its minimum value | value.unsigned_abs() | Returns the matching unsigned type |
| Detect whether integer absolute value fits | value.checked_abs() | Returns Some(value) or None |
| Clamp the minimum integer case | value.saturating_abs() | Returns the largest positive signed value for MIN |
| Keep wrapping arithmetic semantics | value.wrapping_abs() | MIN remains MIN after wrapping |
| Absolute difference between two unsigned values | a.abs_diff(b) | Returns an unsigned distance without creating a negative intermediate |
For unsigned values, abs_diff is often better than converting values to signed integers:
let a: u32 = 3;
let b: u32 = 10;
assert_eq!(a.abs_diff(b), 7);
Cheat Sheet
// Signed integers
let n: i32 = -42;
let positive = n.abs(); // 42
// Floating-point values
let x: f64 = -2.5;
let magnitude = x.abs(); // 2.5
// Absolute difference
let difference = (10_i32 - 27).abs(); // 17
// Unsigned difference
let gap = 3_u32.abs_diff(10); // 7
// Safe magnitude for every i32 value, including i32::MIN
let magnitude: u32 = i32::MIN.unsigned_abs();
// Detect overflow for signed integer MIN
assert_eq!(i32::MIN.checked_abs(), None);
Key rules:
- Use
value.abs(), notstd::num::abs(value). .abs()works on signed integers and floating-point values.- Unsigned types are never negative; use
abs_diffwhen comparing two unsigned values. i8::MIN,i16::MIN,i32::MIN,i64::MIN, andi128::MINcannot be represented as positive values of the same signed type.- Use current Rust documentation; pre-1.0 Rust API documentation is not compatible with modern Rust.
FAQ
How do I get the absolute value of an integer in Rust?
Call .abs() on a signed integer:
let result = (-42_i32).abs();
Is there a std::num::abs function in modern Rust?
No. Modern Rust uses numeric methods such as value.abs(). References to std::num::abs are from old, pre-1.0 Rust documentation.
Does Rust support absolute value for floats?
Yes. Both f32 and f64 provide .abs().
let result = (-1.25_f64).abs();
Why can i32::MIN.abs() fail?
i32::MIN has no positive i32 equivalent. Its magnitude is one greater than i32::MAX, so the result cannot fit in the same signed type.
What should I use instead of abs() for i32::MIN?
Use unsigned_abs() when you need the magnitude, checked_abs() to handle failure, or saturating_abs() when clamping is appropriate.
Can I call .abs() on a u32?
No. A u32 cannot be negative. If you need the distance between two u32 values, use a.abs_diff(b).
Should I compare floating-point numbers with .abs()?
Use .abs() on their difference when comparing within a tolerance: (a - b).abs() <= epsilon.
Mini Project
Description
Build a small function that determines whether a measured temperature is close enough to a target temperature. This models a common validation task: the reading may be above or below the target, but only the size of the error matters.
Goal
Create a Rust program that reports whether a measurement is within an allowed tolerance of a target.
Requirements
Requirement 1
Keep learning
Related questions
Accepting Iterators in Rust Functions with impl Iterator
Learn how to write Rust functions that accept HashMap iterators using generic bounds or impl Iterator, avoiding trait object and lifetime errors.
Access Enum Variant Values in Rust with Pattern Matching
Learn how to extract and print values stored in Rust enum variants using match and if let pattern matching, with practical examples.
Accessing Cargo Package Metadata in Rust
Learn how to read Cargo package metadata like version, name, and authors in Rust using compile-time environment macros.