Math.abs()绝对值取到的数不一定是正数

本文探讨了Java中Math.abs()方法处理整型最小值时的行为特性,通过具体实例展示了Integer.MIN_VALUE作为参数时出现的特殊情况,并分析了背后的原理。

Math.abs()

注释:Note that if the argument is equal to the value of Integer.MIN_VALUE, the most negative representable int value, the result is that same value, which is negative.

源码:

public static int abs(int a) {

        return (a < 0) ? -a : a;

    }

解释:只是对负数做了个取反,对于下面这种临界值

 

实际操作(Integer的最小值操作):

System.out.println(Integer.MIN_VALUE);

System.out.println(Math.abs(Integer.MIN_VALUE));

System.out.println(Math.abs(Integer.MIN_VALUE+1));

结果:

-2147483648

-2147483648

2147483647

 

实际操作(long值操作,然后强转int):

//= 2的32次方+ Integer.MAX_VALUE + 1 = 二进制的31个0+1+1+31个0

long aaa = new BigDecimal(2).pow(32).longValue() + Integer.MAX_VALUE + 1;

System.out.println(aaa);

System.out.println((int)Math.abs(aaa));

结果:

6442450944

-2147483648

 

package com.example.ok; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.font.PDType0Font; import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState; import org.apache.pdfbox.util.Matrix; import java.awt.*; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Paths; //todo:可用版本 public class WatermarkOptimized { // 可配置参 private static final float DENSITY = 2f; // 密度系(降低密度避免重叠) private static final float OPACITY = 0.2f; // 提高可见度 private static final int ROTATION = 45; private static final float FONT_SIZE = 15; public static void main(String[] args) throws Exception { byte[] pdfBytes = Files.readAllBytes(Paths.get("C:\\Users\\z60055043\\Downloads\\111111111111111.pdf")); byte[] watermarked = addWatermark(pdfBytes, "测试cc222@124 12345678912 2025-09-02 09:17:21"); Files.write(Paths.get("output.pdf"), watermarked); } public static byte[] addWatermark(byte[] pdfBytes, String text) throws IOException { try (PDDocument doc = PDDocument.load(new ByteArrayInputStream(pdfBytes)); ByteArrayOutputStream out = new ByteArrayOutputStream()) { // 加载字体(使用try-with-resources确保关闭) try (InputStream fontStream = WatermarkOptimized.class.getResourceAsStream("/font/simhei.ttf")) { PDType0Font font = PDType0Font.load(doc, fontStream); // 遍历所有页面 for (PDPage page : doc.getPages()) { addPageWatermark(doc, page, font, text); } } doc.save(out); return out.toByteArray(); } } private static void addPageWatermark(PDDocument doc, PDPage page, PDType0Font font, String text) throws IOException { try (PDPageContentStream stream = new PDPageContentStream( doc, page, PDPageContentStream.AppendMode.APPEND, true, true)) { PDRectangle pageSize = page.getMediaBox(); float width = pageSize.getWidth(); float height = pageSize.getHeight(); // 正确设置透明度 PDExtendedGraphicsState gs = new PDExtendedGraphicsState(); gs.setNonStrokingAlphaConstant(OPACITY); stream.setGraphicsStateParameters(gs); stream.setFont(font, FONT_SIZE); stream.setNonStrokingColor(Color.GRAY); // 加深颜色提高可见度 // 计算水印单元尺寸 float textWidth = font.getStringWidth(text) * FONT_SIZE / 1000f; float textHeight = font.getBoundingBox().getHeight() * FONT_SIZE / 1000f; // 优化布局算法 double rad = Math.toRadians(ROTATION); float cellWidth = (float) (Math.abs(textWidth * Math.cos(rad)) + Math.abs(textHeight * Math.sin(rad))); float cellHeight = (float) (Math.abs(textWidth * Math.sin(rad)) + Math.abs(textHeight * Math.cos(rad))); // 动态计算行列 int cols = (int) (width / (cellWidth / DENSITY)) + 2; int rows = (int) (height / (cellHeight / DENSITY)) + 2; // 平铺水印(修复偏移计算) for (int row = 0; row < rows; row++) { float y = row * cellHeight / DENSITY; for (int col = 0; col < cols; col++) { float x = col * cellWidth / DENSITY + (row % 2) * cellWidth / (2 * DENSITY); drawWatermarkText(stream, text, font, x, y); } } } } private static void drawWatermarkText(PDPageContentStream stream, String text, PDType0Font font, float x, float y) throws IOException { stream.saveGraphicsState(); // 计算居中位置 float textX = x - font.getStringWidth(text) * FONT_SIZE / 2000f; float textY = y - font.getBoundingBox().getHeight() * FONT_SIZE / 4000f; // 设置旋转(修复旋转中心点) stream.transform(Matrix.getRotateInstance(Math.toRadians(ROTATION), x, y)); stream.beginText(); stream.newLineAtOffset(textX, textY); stream.showText(text); stream.endText(); stream.restoreGraphicsState(); } } 解释上面代码
最新发布
09-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值