Valor Absoluto em Java Explicado: Math.abs(), Armadilhas do MIN_VALUE e BigDecimal

目次

1. O Que Você Vai Aprender Neste Artigo (Resumo Rápido)

Ao trabalhar com Java, você pode precisar calcular o valor absoluto de um número.
A boa notícia é que o Java oferece uma forma simples e padrão de fazer isso — mas também há armadilhas importantes que você deve conhecer.

Neste artigo, você aprenderá:

  • A forma básica e correta de obter um valor absoluto em Java usando Math.abs()
  • Por que Math.abs() não devolve sempre um número positivo
  • O caso especial de Integer.MIN_VALUE e Long.MIN_VALUE
  • Como lidar com segurança valores decimais e dinheiro usando BigDecimal
  • Padrões práticos que você pode usar em aplicações Java do mundo real

Se você quer apenas a resposta curta:

  • ✅ Use Math.abs() na maioria dos casos
  • ⚠️ Tenha cuidado com Integer.MIN_VALUE e Long.MIN_VALUE
  • 💰 Use BigDecimal.abs() para cálculos financeiros e de alta precisão

1.1 A Forma Padrão: Math.abs()

Em Java, a maneira mais comum de calcular um valor absoluto é o método Math.abs().

int x = -10;
int result = Math.abs(x);
System.out.println(result); // 10

O significado é direto:

  • Se o número for positivo, ele é retornado como está
  • Se o número for negativo, o sinal é removido

Como Math.abs() expressa claramente a intenção, ele é preferido em relação a implementações manuais na maioria dos casos.

1.2 Aviso Importante: Valor Absoluto Nem Sempre É Positivo

Muitos iniciantes assumem que valor absoluto sempre significa um número positivo.
Em Java, essa suposição não é sempre verdadeira.

Para certos valores, Math.abs() pode devolver um resultado negativo.

int min = Integer.MIN_VALUE;
int absMin = Math.abs(min);

System.out.println(absMin); // still negative

Esse comportamento não é um bug.
É resultado de como os inteiros são representados internamente no Java.

Explicaremos por que isso acontece e como lidar com isso com segurança nas seções posteriores.

Por enquanto, lembre‑se deste ponto chave:

Math.abs() é seguro para a maioria dos valores, mas não para todos os inteiros possíveis.

1.3 Valor Absoluto para Dinheiro e Números Decimais Precisos

Ao trabalhar com dinheiro ou valores que exigem precisão exata, você não deve usar double.

Em vez disso, o Java fornece a classe BigDecimal, que possui seu próprio método para valores absolutos.

import java.math.BigDecimal;

BigDecimal amount = new BigDecimal("-1234.56");
BigDecimal absAmount = amount.abs();

System.out.println(absAmount); // 1234.56

Observe que:

  • Math.abs() não funciona com BigDecimal
  • Você deve chamar abs() diretamente no objeto BigDecimal

Isso é especialmente importante para aplicações financeiras.

1.4 O Que Vem a Seguir

Nas próximas seções, avançaremos passo a passo:

  • O que realmente significa valor absoluto em programação
  • Como Math.abs() funciona com diferentes tipos de dados
  • O armadilha MIN_VALUE em detalhes
  • Boas práticas para desenvolvimento Java no mundo real

2. O Que É Valor Absoluto? (Distância do Zero)

Antes de mergulhar mais fundo no código Java, é útil entender claramente o que realmente significa valor absoluto.
Esse conceito explica por que Math.abs() se comporta da maneira que se comporta — incluindo suas limitações.

2.1 Definição Básica de Valor Absoluto

O valor absoluto de um número representa sua distância do zero em uma reta numérica.

  • Números positivos → permanecem iguais
  • Números negativos → o sinal é removido
  • Zero → continua zero

Exemplos:

Original ValueAbsolute Value
1010
-1010
00

A ideia principal é que a direção não importa, apenas o tamanho do valor.

2.2 Por Que Valor Absoluto É Útil na Programação

Na programação do mundo real, muitas vezes nos importamos com quão grande é a diferença, não com a direção que ela assume.

Casos de uso comuns incluem:

  • Medir a diferença entre dois valores
  • Verificar se um valor está dentro de uma faixa aceitável
  • Comparar erros ou tolerâncias
  • Normalizar valores de entrada
  • Ordenar por magnitude ao invés de sinal

Por exemplo, ao comparar dois números:

int a = 120;
int b = 95;

int diff = Math.abs(a - b);

Não importa se a - b ou b - a é negativo — queremos apenas a distância.

2.3 Valor Absoluto em Java: Uma Operação Sensível ao Tipo

Em Java, o valor absoluto é tratado como uma operação numérica, não como um construto especial da linguagem.

Isso significa:

  • Tipos primitivos ( int , long , double , etc.) usam Math.abs()
  • Números de alta precisão ( BigDecimal ) usam seu próprio método abs()
  • O comportamento depende do tipo de dado

Isso é importante porque nem todos os tipos numéricos se comportam da mesma forma.

  • Inteiros têm limites fixos
  • Números de ponto flutuante têm valores especiais como NaN e Infinity
  • BigDecimal evita erros de arredondamento, mas funciona de maneira diferente

Entender essa distinção ajudará a evitar bugs sutis mais tarde.

2.4 Por que “Apenas Remover o Sinal de Menos” Não é Suficiente

Um modelo mental comum é:

Valor absoluto = remover o sinal de menos

Embora isso seja geralmente verdadeiro, não é sempre seguro na programação.

Por quê?

  • Tipos numéricos têm faixas limitadas
  • Inteiros Java usam representação em complemento de dois
  • Alguns valores negativos não podem ser convertidos para positivos

É exatamente por isso que certos valores — como Integer.MIN_VALUE — se comportam de maneira diferente.

Exploraremos esse problema em detalhes nas próximas seções.

Por enquanto, lembre‑se:

Valor absoluto é simples em conceito, mas detalhes de implementação importam.

3. Uso Básico de Math.abs() em Java

Agora que entendemos o que significa valor absoluto, vamos ver como usá‑lo em Java.
Na maioria dos casos, Math.abs() é tudo o que você precisa.

3.1 O Exemplo Mais Simples

O método Math.abs() retorna o valor absoluto de um número.

int value = -15;
int result = Math.abs(value);

System.out.println(result); // 15

A intenção é imediatamente clara:

  • Math.abs(x) → “o valor absoluto de x”

Essa legibilidade é uma das maiores razões para usar Math.abs() em vez de escrever sua própria lógica.

3.2 Tipos de Dados Suportados

Math.abs() é sobrecarregado para suportar vários tipos numéricos primitivos.

Input TypeReturn Type
intint
longlong
floatfloat
doubledouble

Um ponto crítico a lembrar:

O tipo de retorno é sempre o mesmo que o tipo de entrada.

Exemplo:

long x = -100L;
long y = Math.abs(x); // still long

Java não amplia automaticamente o tipo ao calcular o valor absoluto.

3.3 Comportamento para Positivo, Negativo e Zero

Para a maioria dos valores, Math.abs() se comporta exatamente como você espera.

System.out.println(Math.abs(10));   // 10
System.out.println(Math.abs(-10));  // 10
System.out.println(Math.abs(0));    // 0

Isso cobre a maioria dos casos do mundo real, por isso muitos tutoriais param aqui.

No entanto, essa simplicidade pode ser enganosa se você não estiver ciente dos casos de borda.

3.4 Usando Math.abs() com Números de Ponto Flutuante

Você também pode usar Math.abs() com double e float.

double d = -3.14;
double absD = Math.abs(d);

System.out.println(absD); // 3.14

Embora isso funcione, números de ponto flutuante introduzem considerações adicionais:

  • Erros de arredondamento
  • Valores especiais como NaN e Infinity
  • A existência de -0.0

Cobriremos esses detalhes em uma seção posterior.

3.5 Por que Você Deve Preferir Math.abs()

Você poderia escrever a lógica de valor absoluto manualmente, por exemplo:

int x = -10;
int abs = x < 0 ? -x : x;

Mas usar Math.abs() geralmente é melhor porque:

  • A intenção é mais clara
  • O código é mais fácil de ler e manter
  • Evita lógica personalizada desnecessária
  • Segue as práticas padrão de Java

Dito isso, Math.abs() não é perfeito.

Na próxima seção, exploraremos a limitação mais importante deste método.

4. Por que Math.abs() Pode Retornar um Valor Negativo (A Armadilha do MIN_VALUE)

Esta seção cobre o caso de borda mais perigoso e incompreendido ao trabalhar com valores absolutos em Java.

Sim — Math.abs() pode retornar um número negativo.

4.1 Os Valores Problemáticos: Integer.MIN_VALUE e Long.MIN_VALUE

Todo tipo inteiro em Java tem um intervalo fixo.

  • int : de -2.147.483.648 a 2.147.483.647
  • long : de -9.223.372.036.854.775.808 a 9.223.372.036.854.775.807

Observe algo importante:

O intervalo negativo é um valor maior que o intervalo positivo.

Exemplo:

System.out.println(Integer.MAX_VALUE); //  2147483647
System.out.println(Integer.MIN_VALUE); // -2147483648

O valor absoluto de -2147483648 seria 2147483648,
mas esse número não pode ser representado por um int.

4.2 O Que Realmente Acontece no Código

Vamos ver o problema em ação.

int min = Integer.MIN_VALUE;
int absMin = Math.abs(min);

System.out.println(absMin); // still negative

Em vez de ficar positivo, o valor permanece negativo.

Esse comportamento costuma surpreender os desenvolvedores, mas é:

  • Não é um bug
  • Não é um problema da JVM
  • Totalmente compatível com a especificação Java

O mesmo problema ocorre para long:

long min = Long.MIN_VALUE;
long absMin = Math.abs(min);

System.out.println(absMin); // still negative

4.3 Por Que Isso Acontece (Complemento de Dois Explicado de Forma Simples)

Java usa complemento de dois para representar inteiros com sinal.

Você não precisa conhecer os detalhes a nível de bits, mas os pontos principais são:

  • Inteiros têm um número fixo de bits
  • Um bit é usado para o sinal
  • Não há contraparte positiva para MIN_VALUE

Quando o Java tenta calcular:

-MIN_VALUE

o resultado estoura e “dá a volta” — terminando no mesmo valor negativo.

4.4 Erro Comum: “Basta Fazer Cast para long

Um equívoco muito comum é:

Se int falhar, eu armazenarei o resultado em um long.

Isso não resolve o problema.

int min = Integer.MIN_VALUE;
long result = Math.abs(min);

Por quê?

Porque Math.abs(min) é avaliado primeiro como int.
O estouro já ocorreu antes de o valor ser atribuído ao long.

4.5 Abordagem Segura #1: Tratar Explicitamente o MIN_VALUE

A solução mais segura e clara é tratar esse caso explicitamente.

int x = Integer.MIN_VALUE;

if (x == Integer.MIN_VALUE) {
    // handle separately (exception, fallback, or special logic)
} else {
    int abs = Math.abs(x);
}

Essa abordagem torna o caso de borda visível e intencional.

4.6 Abordagem Segura #2: Repensar o Design

Se sua lógica supõe que valores absolutos são sempre positivos, considere:

  • Usar long ou BigDecimal desde o início
  • Impedir que MIN_VALUE entre no sistema
  • Tratar esse caso como entrada inválida

Em muitos sistemas reais, a presença de MIN_VALUE já é um cheiro de design.

4.7 Por Que Esse Conhecimento Importa no Código de Produção

Esse caso de borda é perigoso porque:

  • É raro
  • Frequentemente passa nos testes
  • Aparece apenas com valores extremos
  • Pode quebrar silenciosamente a lógica de negócio

Conhecer esse comportamento ajuda a escrever código Java defensivo e pronto para produção.

5. Valores Absolutos com Números de Ponto Flutuante (double / float)

Até agora, focamos em inteiros.
Agora vamos analisar números de ponto flutuante, como double e float, e como os valores absolutos se comportam com eles.

Embora Math.abs() funcione aqui também, números de ponto flutuante introduzem tipos diferentes de armadilhas.

5.1 Uso Básico com double e float

Usar Math.abs() com números de ponto flutuante é exatamente igual ao uso com inteiros.

double x = -12.75;
double abs = Math.abs(x);

System.out.println(abs); // 12.75

Para valores normais, o comportamento é intuitivo e confiável.

5.2 Tratamento de NaN (Not a Number)

Tipos de ponto flutuante podem representar NaN, que significa Not a Number.

double value = Double.NaN;
System.out.println(Math.abs(value)); // NaN

Propriedades importantes do NaN:

  • Math.abs(NaN) retorna NaN
  • NaN == NaN é sempre false
  • Qualquer comparação envolvendo NaN é false

Isso significa que a lógica como a seguinte pode falhar silenciosamente:

if (Math.abs(value) < 1.0) {
    // This will never execute if value is NaN
}

Se seus dados podem conter valores inválidos ou indefinidos, você deve verificar explicitamente por NaN.

5.3 Infinito e Valor Absoluto

Números de ponto flutuante também podem representar infinito.

double posInf = Double.POSITIVE_INFINITY;
double negInf = Double.NEGATIVE_INFINITY;

System.out.println(Math.abs(posInf)); // Infinity
System.out.println(Math.abs(negInf)); // Infinity

Esse comportamento é consistente e previsível, mas frequentemente indica que:

  • Um cálculo saiu do intervalo
  • Uma divisão por zero anterior ocorreu

Na maioria das aplicações, você deve tratar o infinito como um sinal de aviso, não como um resultado válido.

5.4 O Caso Especial de -0.0

Ao contrário dos inteiros, números de ponto flutuante têm tanto 0.0 quanto -0.0.

double z = -0.0;
System.out.println(Math.abs(z)); // 0.0

Embora -0.0 geralmente se comporte como 0.0, há diferenças sutis:

System.out.println(1.0 / 0.0);  // Infinity
System.out.println(1.0 / -0.0); // -Infinity

Tomar o valor absoluto normaliza -0.0 para 0.0,
mas a existência de -0.0 ainda pode afetar cálculos antes de Math.abs() ser aplicado.

5.5 Por que Valores Absolutos de Ponto Flutuante Não Servem para Dinheiro

Embora Math.abs() funcione corretamente com double e float,
esses tipos não são adequados para cálculos financeiros.

As razões incluem:

  • A representação binária causa erros de arredondamento
  • Valores decimais exatos nem sempre podem ser representados
  • Comparações podem falhar inesperadamente

Se você precisa de resultados exatos, especialmente para dinheiro, deve usar BigDecimal.

5.6 Principais Pontos sobre Valores Absolutos de Ponto Flutuante

Ao usar valores absolutos com números de ponto flutuante, lembre-se:

  • Math.abs() funciona como esperado para valores normais
  • NaN permanece NaN
  • Infinito permanece Infinito
  • -0.0 existe e pode ser relevante
  • Números de ponto flutuante não são adequados para dinheiro

6. Valores Absolutos para Dinheiro e Precisão: BigDecimal.abs()

Quando a precisão importa — especialmente em aplicações financeiras e de negócios — números de ponto flutuante não são suficientes.
É aqui que BigDecimal se torna essencial.

6.1 Por que BigDecimal é Necessário

double e float são rápidos, mas não podem representar valores decimais exatamente.

double value = 0.1 + 0.2;
System.out.println(value); // 0.30000000000000004

Esse tipo de erro de arredondamento é inaceitável em casos como:

  • Preços e pagamentos
  • Impostos e taxas
  • Saldo de contas
  • Qualquer cálculo onde a exatidão é necessária

BigDecimal armazena números como valores decimais, evitando esses problemas.

6.2 BigDecimal Não Funciona com Math.abs()

Um erro comum é tentar usar Math.abs() com BigDecimal.

BigDecimal x = new BigDecimal("-100");
// Math.abs(x); // Compile-time error

Isso falha porque BigDecimal não é um tipo primitivo.
Seu valor absoluto deve ser calculado usando um método de instância.

6.3 A Forma Correta: BigDecimal.abs()

Para obter o valor absoluto de um BigDecimal, chame abs() diretamente no objeto.

import java.math.BigDecimal;

BigDecimal amount = new BigDecimal("-1234.56");
BigDecimal absAmount = amount.abs();

System.out.println(absAmount); // 1234.56

Características importantes:

  • BigDecimal é imutável
  • abs() retorna um novo objeto
  • O valor original permanece inalterado

6.4 Usando MathContext para Controle de Precisão

import java.math.BigDecimal;
import java.math.MathContext;

BigDecimal value = new BigDecimal("-1234.56789");
BigDecimal abs = value.abs(new MathContext(6));

System.out.println(abs); // valor absoluto com precisão aplicada

This is useful when:

  • Internal calculations require fixed precision
  • Regulatory or business rules apply
  • You want consistent rounding behavior

6.5 Common Real-World Use Cases

Ensuring Positive Differences

BigDecimal before = new BigDecimal("1000");
BigDecimal after  = new BigDecimal("750");

BigDecimal difference = after.subtract(before).abs();
System.out.println(difference); // 250

Normalizing External Input

BigDecimal input = new BigDecimal("-500");
BigDecimal normalized = input.abs();

This pattern is common when processing user input or external data feeds.

6.6 When You Should Choose BigDecimal

Use BigDecimal when:

  • You are working with money
  • Precision is critical
  • Rounding errors are unacceptable
  • You want to avoid integer overflow issues like MIN_VALUE

Avoid it when:

  • Performance is critical
  • Approximation is acceptable
  • The values are simple and bounded

6.7 Summary: BigDecimal.abs() Is the Safe Choice

For financial and high-precision calculations:

  • Do not use double
  • Do not use Math.abs()
  • Use BigDecimal.abs()

This choice prevents subtle bugs and ensures reliable results.

7. Writing Your Own Absolute Value Logic (And Why You Usually Shouldn’t)

Some developers prefer to write absolute value logic manually instead of using Math.abs().
While this may look simple, it often introduces hidden risks and offers no real advantage.

7.1 A Common Manual Implementation

A typical custom implementation looks like this:

int x = -20;
int abs = x < 0 ? -x : x;

System.out.println(abs); // 20

At first glance, this seems perfectly reasonable:

  • If the value is negative, flip the sign
  • Otherwise, return the value as-is

7.2 The MIN_VALUE Problem Still Exists

Unfortunately, this manual approach does not fix the MIN_VALUE issue.

int x = Integer.MIN_VALUE;
int abs = x < 0 ? -x : x;

System.out.println(abs); // ainda negativo

Why?

Because the problem is not the implementation, but the numeric limits of the data type.

  • -Integer.MIN_VALUE cannot be represented as an int
  • Overflow occurs before you can “fix” it

So even custom logic behaves exactly like Math.abs() in this case.

7.3 Readability and Intent Matter More Than Cleverness

Compare these two versions:

int a = x < 0 ? -x : x;
int a = Math.abs(x);

The second version is clearer because:

  • The intent is explicit
  • Anyone reading the code understands it immediately
  • There is no need to mentally parse the condition

In professional codebases, clarity is more important than brevity.

7.4 Performance Differences Are Negligible

Some developers worry that Math.abs() might be slower than manual logic.

In modern Java:

  • The JIT compiler optimizes both approaches
  • The performance difference is effectively zero
  • Micro-optimizations here are pointless

Choosing readability and safety is the correct decision.

7.5 When Manual Logic Might Make Sense

There are very limited cases where custom logic is acceptable:

  • Teaching or learning basic control flow
  • Writing minimal examples or pseudocode
  • Implementing defensive checks around MIN_VALUE

Even then, you should clearly document the reason.

7.6 Recommended Best Practices

Follow these guidelines:

  • ✅ Use Math.abs() for primitive types
  • ✅ Use BigDecimal.abs() for financial values
  • ❌ Avoid reinventing standard library behavior
  • ⚠️ Always consider edge cases like MIN_VALUE

8. Practical Absolute Value Patterns (Copy & Paste Recipes)

This section shows real-world patterns where absolute values are commonly used in Java applications.
All examples are safe, readable, and ready to copy.

8.1 Getting the Difference Between Two Values

Um caso de uso muito comum é encontrar a diferença independentemente da direção.

int a = 120;
int b = 95;

int diff = Math.abs(a - b);
System.out.println(diff); // 25

Este padrão é usado para:

  • Diferenças de pontuação
  • Comparações de contagem
  • Cálculos de distância
  • Diferenças de versão ou deslocamento

8.2 Comparando Valores com uma Tolerância (Margem de Erro)

A igualdade exata costuma ser pouco confiável com números de ponto flutuante.
Em vez disso, compare a diferença absoluta a uma tolerância.

double expected = 100.0;
double actual   = 99.9998;
double tolerance = 0.01;

if (Math.abs(expected - actual) <= tolerance) {
    // Within acceptable range
}

Isso é especialmente útil em:

  • Testes unitários
  • Sistemas de medição
  • Cálculos científicos ou estatísticos

8.3 Ordenando por Valor Absoluto

Às vezes você quer ordenar valores por magnitude, não por sinal.

List<Integer> numbers = Arrays.asList(-3, 10, -1, 5);

numbers.sort(Comparator.comparingInt(Math::abs));
System.out.println(numbers); // [-1, -3, 5, 10]

Casos de uso típicos incluem:

  • Classificação por desvio
  • Seleção do valor mais próximo
  • Ordenação baseada em impacto

8.4 Normalizando Valores de Entrada

Entradas externas podem conter valores negativos inesperados.
Se a negatividade não tem significado, normalize a entrada.

int input = -50;
int normalized = Math.abs(input);

Este padrão é comum para:

  • Quantidades
  • Tamanhos
  • Valores de configuração

⚠️ Sempre garanta que MIN_VALUE não possa aparecer, ou trate‑o explicitamente.

8.5 Diferenças Financeiras com BigDecimal

Para cálculos relacionados a dinheiro, use BigDecimal e abs().

BigDecimal before = new BigDecimal("1500");
BigDecimal after  = new BigDecimal("1800");

BigDecimal difference = after.subtract(before).abs();
System.out.println(difference); // 300

Isso evita:

  • Erros de arredondamento de ponto flutuante
  • Problemas de overflow de inteiros
  • Comparações incorretas

8.6 Verificações de Intervalo e Limites

Valores absolutos são úteis para verificar se um valor está dentro de um intervalo ao redor de um centro.

int center = 100;
int value  = 92;

if (Math.abs(value - center) <= 10) {
    // Within range
}

Aplicações comuns:

  • Limiares de sensores
  • Lógica de encaixe da UI
  • Regras de validação

8.7 Dicas Práticas Principais

Ao usar valores absolutos em aplicações reais:

  • Conheça seu tipo de dado
  • Considere casos de borda
  • Escolha a precisão intencionalmente
  • Não presuma que “absoluto” signifique “seguro”

9. Resumo e Principais Conclusões

Vamos resumir tudo que abordamos sobre valores absolutos em Java e destacar os pontos mais importantes que você deve lembrar.

9.1 Use Math.abs() como a Escolha Padrão

Para a maioria das situações, Math.abs() é a solução correta e recomendada.

  • Funciona com int, long, float e double
  • Clara e expressiva
  • Parte da biblioteca padrão Java
  • Fácil de ler e manter

Se você não tem certeza, comece com Math.abs().

9.2 MIN_VALUE é a Única Exceção Crítica

Integer.MIN_VALUE e Long.MIN_VALUE são casos especiais.

  • Seus valores absolutos não podem ser representados
  • Math.abs() pode retornar um número negativo
  • Esse comportamento é definido pela especificação Java

Regra chave:

Nunca presuma que Math.abs() sempre retorne um valor positivo.

Se esse valor puder aparecer nos seus dados, trate‑o explicitamente ou redesenhe a lógica.

9.3 Valores Absolutos de Ponto Flutuante Têm suas Próprias Armadilhas

Ao usar double ou float:

  • NaN permanece NaN
  • Infinity permanece Infinity
  • -0.0 existe
  • Erros de arredondamento são inevitáveis

Esses tipos são adequados para aproximação, mas não para dinheiro.

9.4 Use BigDecimal.abs() para Dinheiro e Precisão

Para cálculos financeiros e de alta precisão:

  • Não use double
  • Não use Math.abs()
  • Use BigDecimal.abs()

Isso garante:

  • Representação decimal exata
  • Sem surpresas de arredondamento
  • Sem problemas de overflow de inteiros

9.5 Não Reinvente a Lógica de Valor Absoluto

Escrevendo seu próprio código de valor absoluto:

  • Não corrige casos de borda
  • Adiciona complexidade desnecessária
  • Reduz a legibilidade

APIs padrão existem por uma razão. Use-as.

9.6 Pense sobre Entrada e Design, Não Apenas na Fórmula

Valor absoluto é simples na teoria, mas seu uso seguro depende de:

  • O tipo de dado
  • Faixas de entrada possíveis
  • Regras de negócio
  • Casos de borda

Um bom código Java vem de compreender restrições, não apenas aplicar fórmulas.

FAQ: Perguntas Comuns sobre Valores Absolutos em Java

Q1. O Math.abs() sempre retorna um número positivo?

Não.
Para Integer.MIN_VALUE e Long.MIN_VALUE, o resultado ainda pode ser negativo.

Q2. Esse comportamento é um bug do Java?

Não.
É uma consequência direta da representação de inteiros de tamanho fixo e é um comportamento totalmente documentado.

Q3. Posso corrigir o problema convertendo para long?

Não.
O overflow ocorre antes da conversão se a entrada for int.

Q4. Como obtenho o valor absoluto de um BigDecimal?

Use o método abs() no objeto:

BigDecimal value = new BigDecimal("-100");
BigDecimal abs = value.abs();

Q5. É seguro usar valores absolutos para comparações?

Sim, mas somente se você:

  • Escolher o tipo de dado correto
  • Levar em conta a precisão e casos de borda
  • Usar tolerâncias para números de ponto flutuante

Considerações Finais

Valor absoluto é um dos conceitos matemáticos mais simples —
mas em Java, ele tem detalhes técnicos importantes que importam em aplicações reais.

Ao compreender esses detalhes, você pode escrever:

  • Código mais seguro
  • Código mais claro
  • Programas Java mais profissionais