Math Functions

Lesson 78: Using abs() Math Function

Learn how abs() converts negative values into positive magnitude for cleaner comparisons and control logic.

Progress indicator

Lesson 78 of 78

Learning Objectives

  • Understand what abs() does mathematically and why sign is removed in magnitude comparisons.
  • Apply the absolute value concept to sensor error, tolerance windows, and control decisions.
  • Use abs() inside embedded logic that compares distance from target rather than direction.
  • Understand type behavior for int/long and when float logic should use fabs()-style handling.
  • Avoid common mistakes such as sign-loss bugs, type confusion, and extreme-value edge cases.

Concept Explanation

What is abs()

abs() returns the absolute value of a number. It removes the sign and gives only the size (magnitude) of the value.

In Arduino projects, abs() is often used when you only care how far a value is from a target, not whether it is above or below the target.

abs() Syntax

Basic syntax: abs(x), where x is usually an integer expression.

  • abs(-25) returns 25.
  • abs(25) returns 25.
  • abs(0) returns 0.
  • abs(sensorValue - setPoint) returns non-negative error distance.

How abs() Works

If the input is negative, abs() flips sign to positive. If input is zero or positive, abs() returns it unchanged.

  1. Evaluate expression inside abs(...).
  2. Check whether result is less than zero.
  3. If negative, return -value; otherwise return value directly.

Absolute Value Concept

Absolute value means “distance from zero.” In control systems, this is useful for measuring how far a sensor is from a target regardless of being above or below it.

Real example: if setPoint is 500, sensor values 470 and 530 both have error magnitude 30. abs() makes both values comparable with one threshold rule.

abs() with Different Data Types

  • Commonly used with int and long values.
  • For floating-point numbers, C/C++ style often uses fabs().
  • When using mixed types, be aware of implicit conversion rules.
  • For very large negative integer edge values, overflow edge cases can exist.

Beginner rule: if your value is decimal, verify float-safe function behavior in your platform/library and keep types explicit.

When to Use abs()

  • Error/tolerance checks in sensor control logic.
  • Difference comparison where sign does not matter.
  • Simple distance-like calculations in embedded loops.
  • Detecting vibration/noise amplitude around a baseline value.

Example Code

This example uses abs() to detect if sensor value is outside tolerance range.

const int LED_PIN = 2;
int setPoint = 500;
int sensorValue = 460;
int tolerance = 30;

void setup() {
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  int error = sensorValue - setPoint;
  int distanceFromTarget = abs(error);

  Serial.print("sensorValue: ");
  Serial.print(sensorValue);
  Serial.print(" | setPoint: ");
  Serial.print(setPoint);
  Serial.print(" | abs(error): ");
  Serial.println(distanceFromTarget);

  if (distanceFromTarget > tolerance) {
    digitalWrite(LED_PIN, HIGH);
    Serial.println("Outside tolerance -> LED ON");
  } else {
    digitalWrite(LED_PIN, LOW);
    Serial.println("Within tolerance -> LED OFF");
  }

  sensorValue = sensorValue + 15;
  if (sensorValue > 560) {
    sensorValue = 440;
  }

  delay(700);
}

Example Code Explanation

  1. setPoint defines target sensor value and tolerance defines allowed range.
  2. error = sensorValue - setPoint computes signed error (positive or negative).
  3. distanceFromTarget = abs(error) converts signed error to pure magnitude.
  4. Serial prints all key values so learners can inspect each calculation step.
  5. Condition distanceFromTarget > tolerance checks if system is outside acceptable range.
  6. Outside tolerance: LED ON plus warning message.
  7. Inside tolerance: LED OFF plus stable status message.
  8. sensorValue is updated to simulate live changing input.
  9. Wrap-around reset keeps simulation loop repeating with varied error signs.

What Happens Inside

  1. CPU computes subtraction result in integer arithmetic (signed error).
  2. abs() performs sign normalization to produce a non-negative magnitude.
  3. Magnitude value is compared with tolerance threshold.
  4. Branch logic toggles LED state based on threshold result.
  5. Serial output reports intermediate values for runtime observability.
  6. Loop repeats, continuously re-evaluating magnitude-based control behavior.

Common Mistakes with abs()

  • Using abs() when sign actually matters for logic direction.
  • Assuming abs() is always safe for every integer edge value.
  • Using abs() on floats without checking preferred function/library behavior.
  • Comparing raw signed error to tolerance instead of comparing absolute error.
  • Using abs() repeatedly on the same value instead of computing once and reusing it.

Best Practices for abs()

  • Use abs() for tolerance windows and magnitude-only comparisons.
  • Keep variable types explicit and consistent in math expressions.
  • Print intermediate values during debugging to verify abs() behavior.
  • Store absolute error in a named variable (like distanceFromTarget) for readability.
  • Document threshold meaning (units and tolerance rule) near your comparison logic.

Try it now

Open the simulator workspace and watch how abs(error) drives tolerance-based LED logic.

Run in Simulator