Round command argument before using
One approach would be this. ceil
and floor
are alternatives to round
. There are also command versions of each, as Alan Munn mentions in a comment, i.e. \pgfmathround{#1}
, \pgfmathceil{#1}
, \pgfmathfloor{#1}
.
\documentclass{article}
\usepackage{pgffor}
\newcommand{\myrepeat}[2]{%
\pgfmathparse{round(#1)}% set rounding function here
\foreach \n in {1,...,\pgfmathresult}{#2}}
\begin{document}
\myrepeat{3.2}{x} % should print xxx
\myrepeat{3.7}{x} % should print xxxx
\end{document}
Here's a fairly general macro where you can set the mode as an optional argument: choose between round
(default), floor
, ceil
or nearest
.
The \generalrepeat
macro accepts the starting point (an integer), the step (an integer, default 1) and the end point (a floating point number).
The \myrepeat
macro is a reduced version, always starting from 1 with step 1.
In the final argument (code to repeat), the current value in the loop is denoted by #1
.
\documentclass{article}
\usepackage{xfp}
\ExplSyntaxOn
\NewDocumentCommand{\generalrepeat}
{
O{round} % the mode
m % the starting point
O{1} % the step
m % the final point
+m % the code to repeat (can contain \par)
}
{
\klinke_repeat_general:nnnnn { #1 } { #2 } { #3 } { #4 } { #5 }
}
\NewDocumentCommand{\myrepeat}
{
O{round} % the mode
m % the final point
+m % the code to repeat (can contain \par)
}
{
\klinke_repeat_general:nnnnn { #1 } { 1 } { 1 } { #2 } { #3 }
}
\cs_new_protected:Nn \klinke_repeat_general:nnnnn
{
\cs_set_eq:Nc \__klinke_repeat_mode:n { __klinke_repeat_#1:n }
\cs_set_protected:Nn \__klinke_repeat_code:n { #5 }
\int_step_function:nnnN
{ #2 } % start
{ #3 } % step
{ \__klinke_repeat_mode:n { #4 } } % end
\__klinke_repeat_code:n % action
}
\cs_new:Nn \__klinke_repeat_round:n { \fp_eval:n { round(#1,0,1) } }
\cs_new:Nn \__klinke_repeat_floor:n { \fp_eval:n { floor(#1,0) } }
\cs_new:Nn \__klinke_repeat_ceil:n { \fp_eval:n { ceil(#1,0) } }
\cs_new:Nn \__klinke_repeat_nearest:n
{
\fp_eval:n { #1 - floor(#1,0) < 0.5 ? floor(#1,0) : ceil(#1,0) }
}
\ExplSyntaxOff
\begin{document}
\generalrepeat{1}{3.4}{#1 }---
\generalrepeat{1}{3.5}{#1 }---
\generalrepeat{1}{3.6}{#1 }
\generalrepeat[ceil]{1}{3.4}{#1 }---
\generalrepeat[ceil]{1}{3.5}{#1 }---
\generalrepeat[ceil]{1}{3.6}{#1 }
\generalrepeat[floor]{1}{3.4}{#1 }---
\generalrepeat[floor]{1}{3.5}{#1 }---
\generalrepeat[floor]{1}{3.6}{#1 }
\generalrepeat[nearest]{1}{3.4}{#1 }---
\generalrepeat[nearest]{1}{3.5}{#1 }---
\generalrepeat[nearest]{1}{3.6}{#1 }
\myrepeat{3.4}{x}---\myrepeat[floor]{3.4}{x}---%
\myrepeat[ceil]{3.4}{x}---\myrepeat[nearest]{3.4}{x}
\myrepeat{3.5}{x}---\myrepeat[floor]{3.5}{x}---%
\myrepeat[ceil]{3.5}{x}---\myrepeat[nearest]{3.5}{x}
\myrepeat{3.6}{x}---\myrepeat[floor]{3.6}{x}---%
\myrepeat[ceil]{3.6}{x}---\myrepeat[nearest]{3.6}{x}
\end{document}
Both round
and nearest
integer are implemented to go upward in case of a tie (the 3.5 case).
You can use the expandable functionality of xfp
:
\documentclass{article}
\usepackage{pgffor,xfp}
\newcommand{\myrepeat}[2]{\foreach \n in {1,...,\fpeval{floor(#1)}}{#2}}
\begin{document}
\myrepeat{6}{x} % prints xxxxxx
\myrepeat{3.2}{x} % prints xxx
\myrepeat{8.1 * sin(pi / 6)}{x}% prints xxxx sin(pi/6) = 1/2; 8.1 * 1/2 = 4.05
\end{document}
You can use ceiling(#1)
, or round(#1,0)
, or whatever calculation you want.