Here's a home-grown version with tokcycle
(i.e., no pgf). It rounds to a level specified in \savedigits
.
\documentclass{article}
\usepackage{tokcycle}
\newcounter{decs}
\def\savedigits{2}
\newif\iferr
\newif\iffounddot
\newcommand\roundit[1]{%
\errfalse
\setcounter{decs}{0}%
\founddotfalse% MADE T WHEN DECIMAL HAS BEEN 1ST LOCATED
\tokcycle% CYCLE THROOUGH EACH TOKEN
{\tctestifx{.##1}%
{\addcytoks{##1}%
\iffounddot\errtrue\fi\founddottrue\setcounter{decs}{0}}% IF .
{\tctestifnum{`##1>`/}%
{\tctestifnum{`##1<`:}%
{%
\iffounddot\stepcounter{decs}\fi%
\ifnum\thedecs<\savedigits\relax\addcytoks{##1}\else
\ifnum\thedecs=\savedigits\relax\addcytoks{\roundlast ##1}\else
\ifnum\thedecs=\numexpr\savedigits+1 \addcytoks{##1}\fi\fi\fi
}%
{\errtrue}% IF ASCII > `9
}%
{\errtrue}% IF ASCII < `0
}%
}% APPLY ABOVE LOGIC FOR CHAR TOKENS
{\errtrue}% IF BRACES
{\errtrue}% IF CONTROL SEQUENCE
{}% IGNORE SPACES
{#1}% THE ARGUMENT
\addcytoks{\space}
\iferr ERROR\else\the\cytoks\fi
}
\newcommand\roundlast[2]{\ifnum0#2>4 \the\numexpr#1+1 \else#1\fi}
\begin{document}
\noindent
0) \roundit{0.09155}\\
1) \roundit{12.3}\\
2) \roundit{0.127}\\
3) \roundit{1.2.3}\\
4) \roundit{1.3\today}\\
5) \roundit{321.345 678}\\
6) \roundit{000321.305}\\
7) \roundit{.006 300 345}\\
8) \roundit{0003x1.345}\\
9) \roundit{1230}\\
9a) \roundit{1230.}\\
A) \roundit{123.078}\\
B) \roundit{0003;345}\\
\end{document}

If you don't mind dispensing with the error checking, here is a different token cycle that employs a new (2021-05-27) feature to look-ahead at the input stream pushing and popping tokens as needed, as well as to truncate the cycle based on what occurs inside the cycle.
\documentclass{article}
\usepackage{tokcycle}[2021-05-27]
\newcommand\roundit[1]{\tokcycle
{\ifx.##1.%
\tcpop\tenths
\tcpop\hundredths
\tcpop\thousandths
\ifnum 0\thousandths>4
\tenths\the\numexpr\hundredths+1 \else\tenths\hundredths\fi
\tcpush{\noexpand\truncatecycle}%
\else
##1%
\fi
}% DO THE ABOVE FOR EACH CHARACTER
{\processtoks{\truncatecycle}}% IF GROUP
{\truncatecycle}% IF MACRO
{##1}% IF SPACE
{#1}}
\begin{document}
\noindent
0) \roundit{0.09155}\\
1) \roundit{12.3}\\
2) \roundit{0.127}\\
5) \roundit{321.345 678}\\
6) \roundit{000321.305}\\
7) \roundit{.006 300 345}\\
9) \roundit{1230}\\
9a) \roundit{1230.}\\
A) \roundit{123.078}\\
\end{document}

\pgfmathsetmacro\xx{int(\x*100)/100}
you mean? Don't know if it will always work though, or if you'll get ...999999 or ....0000001 in some cases. (Why not use\pgfmathprintnumber
?)int(100*(\x-frac(100*\x)/100))/100
. PS: Why or why not is not the question here. It's good to have a working solution for this. It is not always possible to predict when these will be needed.round
, notint
, but anyways: your version doesn't always give the correct results, and mine gives e.g. 0.06999 instead of 0.07. Try this for example:\documentclass[margin=5pt, varwidth]{standalone} \usepackage{tikz} \begin{document} \pgfmathsetseed{42} \foreach\i in {1,...,100}{\pgfmathsetmacro\x{rnd}\pgfmathsetmacro\xx{round(\x*100)/100}\pgfmathsetmacro\xxx{round(100*(\x-frac(100*\x)/100))/100}$x = \x$, but $x \approx \pgfmathprintnumber[fixed, precision=2]{\x}$ and $x\approx \xx$ and $x\approx \xxx$ \\}\end{document}
xfp
the following works out of the box:\fpeval{round(0.09, 2)}
.