Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

math error #2

Open
lungetech opened this Issue Nov 4, 2013 · 6 comments

Comments

Projects
None yet
5 participants
@ghost
Copy link

commented Nov 4, 2013

The addition provided by the template is wrong.

100.08+81.32+65.68+121.97+50.04 = 419.09

The PDF shows the subtotal as 419.08.

@johannesbottcher

This comment has been minimized.

Copy link

commented Apr 10, 2015

Unfortunately, still not sorted as seen by the following two examples, one running with the invoice class here, the other running with the invoice class available at latex-templates.com. A post at LateX-Community.org made me aware.

Running here

\documentclass{invoice}
\begin{document}
\hourlyrate{180}
\begin{invoiceTable}
\hourrow{January 3, 2011}{1}
\hourrow{January 7, 2011}{.7}
\end{invoiceTable}
\end{document}

older invoice class distributed at latex-templates

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Invoice Template
% LaTeX Template
% Version 1.0 (3/11/12)
%
% This template has been downloaded from:
% http://www.LaTeXTemplates.com
%
% Original author:
% Trey Hunner (http://www.treyhunner.com/)
%
% License:
% CC BY-NC-SA 3.0 (http://creativecommons.org/licenses/by-nc-sa/3.0/)
%
% Important note:
% This template requires the invoice.cls file to be in the same directory as 
% the .tex file. The invoice.cls file provides the style used for structuring the
% document.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\documentclass{invoice} % Use the custom invoice class (invoice.cls)
\begin{document}
\begin{invoiceTable}
    \hourrow{bla bla}{1.0}{180}
%   \hourrow{bla bla}{0.20}{180}
    \hourrow{bla bla}{0.70}{180}
    \subtotal
\end{invoiceTable}
\end{document}

Thanks for taking a look at this.

@johannesbottcher

This comment has been minimized.

Copy link

commented Aug 28, 2015

New instance of the problem at TeX.Stackexchange

Quoting @ufischer:

In the version on github \hourrow has only two arguments and I don't get your rounding error. But the example in the issues tracker still gives wrong results. The math in the package is faulty. It uses \real from the calc package to handle decimals like 0.7 and seems not to know that you can get rounding errors and that multiplying everything with 1000 isn't enough. Throw it away. One would have to replace all calculations with something better to get something usable.

@treyhunner

This comment has been minimized.

Copy link
Owner

commented Aug 28, 2015

Thanks for adding more context @johannesbottcher. I haven't experienced this problem before, but I can't argue against the math in this package probably being faulty. I am a LaTeX novice and I don't actually know what I'm doing. 😅

If anyone has a solution for the math errors, I'd gladly welcome a pull request. 😸

@eg9

This comment has been minimized.

Copy link

commented Sep 29, 2016

Here is a fixed version for your class

%%% modified by egreg for TeX.Stackexchange
%%% http://tex.stackexchange.com/questions/331898/
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  Copyright (c) 2011 Trey Hunner                                          %
%                                                                          %
%  Permission is hereby granted, free of charge, to any person obtaining   %
%  a copy of this software and associated documentation files (the         %
%  "Software"), to deal in the Software without restriction, including     %
%  without limitation the rights to use, copy, modify, merge, publish,     %
%  distribute, sublicense, and/or sell copies of the Software, and to      %
%  permit persons to whom the Software is furnished to do so, subject to   %
%  the following conditions:                                               %
%                                                                          %
%  The above copyright notice and this permission notice shall be          %
%  included in all copies or substantial portions of the Software.         %
%                                                                          %
%  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,         %
%  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF      %
%  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND                   %
%  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE  %
%  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION  %
%  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION   %
%  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.         %
%                                                                          %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ProvidesClass{invoice3}

\LoadClass[12pt]{article}

\usepackage[letterpaper,hmargin=0.79in,vmargin=0.79in]{geometry}
\usepackage[parfill]{parskip} % Do not indent paragraphs
\usepackage{xparse} % Fixed-point arithmetic, among many other things
\usepackage{siunitx} % for displaying numbers
\usepackage{longtable}

\pagestyle{empty} % No page numbers
\linespread{1.5}

\setlength{\doublerulesep}{\arrayrulewidth} % Double rules look like one thick one

% Command for setting a default hourly rate
\ExplSyntaxOn
\NewDocumentCommand{\hourlyrate}{m}
 {
  \fp_set:Nn \l_invoice_hourlyrate_fp { #1 }
 }
\fp_new:N \l_invoice_hourlyrate_fp
\hourlyrate{1} % initialize

\NewDocumentCommand{\feetype}{m}
 {
  \textbf{#1} \\
 }

% Counters for totaling up hours and dollars
\fp_new:N \g_invoice_hours_fp
\fp_new:N \g_invoice_subhours_fp
\fp_new:N \g_invoice_cost_fp
\fp_new:N \g_invoice_subcost_fp

% Formats input number with 2 digits after the decimal place
\NewDocumentCommand{\formatNumber}{m}
 {
  \num[detect-all,round-integer-to-decimal,round-mode=places,round-precision=2]{\fp_eval:n {#1}}
 }

% Returns the total of counter
\NewDocumentCommand{\total}{m}
 {
  \formatNumber{#1}
 }

% Create a new row from title, unit quantity, unit rate, and unit name
\NewDocumentCommand{\unitrow}{mmmm}
 {
  \fp_gadd:Nn \g_invoice_cost_fp { (#2) * (#3) }
  \fp_gadd:Nn \g_invoice_subcost_fp { (#2) * (#3) }
  #1 &
  \formatNumber{#2} ~ #4 &
  \$\formatNumber{#3} &
  \$\formatNumber{#2 * #3}
  \\
 }
% Create a new row from title and expense amount
\NewDocumentCommand{\feerow}{mm}
 {
  \fp_gadd:Nn \g_invoice_cost_fp { #2 }
  \fp_gadd:Nn \g_invoice_subcost_fp { #2 }
  #1 & & \$\formatNumber{#2} & \$\formatNumber{#2} \\
 }
\DeclareExpandableDocumentCommand{\subtotal}{}
 {
  \hline
  \subtotalaux
 }
\NewDocumentCommand{\subtotalaux}{s}
 {
  \textbf{Subtotal} &
  \IfBooleanF{#1}{\textbf{\total{\g_invoice_subhours_fp} ~ hours}} &
  &
  \textbf{\$\formatNumber{\g_invoice_subcost_fp}}
  \fp_gzero:N \g_invoice_subcost_fp
  \IfBooleanF{#1}{\fp_gzero:N \g_invoice_subhours_fp}
  \\*[1.5ex]
 }
% Create a new row from date and hours worked (use stored fee type and hourly rate)
\NewDocumentCommand{\hourrow}{mm}
 {
  \fp_gadd:Nn \g_invoice_hours_fp { #2 }
  \fp_gadd:Nn \g_invoice_subhours_fp { #2 }
  \unitrow{#1}{#2}{\l_invoice_hourlyrate_fp}{hours}
 }

% Create an invoice table
\NewDocumentEnvironment{invoiceTable}{}
 {
  \setlength{\tabcolsep}{0.8ex}
  \setlength\LTleft{0pt}
  \setlength\LTright{0pt}
  \begin{longtable}{@{\extracolsep{\fill}\hspace{\tabcolsep}} l r r r }
  \hline
  \textbf{Description~of~Services} &
  \multicolumn{1}{c}{\bfseries Quantity} &
  \multicolumn{1}{c}{\bfseries Unit~Price} &
  \multicolumn{1}{c}{\bfseries Amount} \\*
  \hline\hline
  \endhead
 }
 {
  \\*[-\normalbaselineskip]
  \hline\hline\hline
  {\bfseries Balance Due} & & & {\bfseries \$\formatNumber{\g_invoice_cost_fp}} \\
  \end{longtable}
 }
\ExplSyntaxOff
@eg9

This comment has been minimized.

Copy link

commented Sep 29, 2016

Here's another version using only fp

%%% modified by egreg
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  Copyright (c) 2011 Trey Hunner                                          %
%                                                                          %
%  Permission is hereby granted, free of charge, to any person obtaining   %
%  a copy of this software and associated documentation files (the         %
%  "Software"), to deal in the Software without restriction, including     %
%  without limitation the rights to use, copy, modify, merge, publish,     %
%  distribute, sublicense, and/or sell copies of the Software, and to      %
%  permit persons to whom the Software is furnished to do so, subject to   %
%  the following conditions:                                               %
%                                                                          %
%  The above copyright notice and this permission notice shall be          %
%  included in all copies or substantial portions of the Software.         %
%                                                                          %
%  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,         %
%  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF      %
%  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND                   %
%  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE  %
%  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION  %
%  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION   %
%  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.         %
%                                                                          %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ProvidesClass{invoice}

\LoadClass[12pt]{article}

\usepackage[letterpaper,hmargin=0.79in,vmargin=0.79in]{geometry}
\usepackage[parfill]{parskip} % Do not indent paragraphs
\usepackage{fp} % Fixed-point arithmetic
\usepackage{longtable}

\pagestyle{empty} % No page numbers
\linespread{1.5}

\setlength{\doublerulesep}{\arrayrulewidth} % Double rules look like one thick one

% variables for total cost and subcost, total hours and subhours
\def\totalcost{0}\def\subcost{0}
\def\totalhours{0}\def\subhours{0}

% Command for setting a default hourly rate
\newcommand{\hourlyrate}[1]{\def \@hourlyrate {#1}}
\hourlyrate{1}
\newcommand{\feetype}[1]{
    \textbf{#1}
    \\
}

% Formats inputed number with 2 digits after the decimal place
\newcommand*{\formatNumber}[1]{\FPround{\temp}{#1}{2}\temp} %

% Returns the total of counter
\newcommand*{\total}[1]{\formatNumber{#1}}

% Create an invoice table
\newenvironment{invoiceTable}{%
    % Create a new row from title, unit quantity, unit rate, and unit name
    \newcommand*{\unitrow}[4]{%
         \FPmul{\tempa}{##2}{##3}%
         \FPadd{\tempb}{\totalcost}{\tempa}%
         \global\let\totalcost\tempb
         \FPadd{\tempb}{\subcost}{\tempa}%
         \global\let\subcost\tempb
         ##1 & \formatNumber{##2} ##4 & \$\formatNumber{##3} & \$\FPmul{\temp}{##2}{##3}\formatNumber{\temp}%
         \\
    }%
    % Create a new row from title and expense amount
    \newcommand*{\feerow}[2]{%
         \FPadd{\tempa}{\totalcost}{##2}%
         \global\let\totalcost\tempa
         \FPadd{\tempa}{\subcost}{##2}%
         \global\let\subcost\tempa
         ##1 & & \$\formatNumber{##2} & \$\formatNumber{##2}%
         \\
    }%
    \newcommand{\subtotalNoStar}{%
        \textbf{Subtotal} & \textbf{\total{\subhours} hours} &  & \textbf{\$\total{\subcost}}%
        \gdef\subcost{0}%
        \gdef\subhours{0}%
        \\*[1.5ex]
    }%
    \newcommand{\subtotalStar}{%
        \textbf{Subtotal} & & & \textbf{\$\total{\subcost}}
        \gdef\subcost{0}%
        \\*[1.5ex]
    }%
    \newcommand{\subtotal}{%
         \hline
         \@ifstar
         \subtotalStar
         \subtotalNoStar
    }%
    % Create a new row from date and hours worked (use stored fee type and hourly rate)
    \newcommand*{\hourrow}[2]{%
        \FPadd{\tempa}{\totalhours}{##2}%
        \global\let\totalhours\tempa
        \FPadd{\tempa}{\subhours}{##2}%
        \global\let\subhours\tempa
        \unitrow{##1}{##2}{\@hourlyrate}{hours}%
    }%
    \setlength{\tabcolsep}{0.8ex}%
    \setlength\LTleft{0pt}%
    \setlength\LTright{0pt}%
    \begin{longtable}{@{\extracolsep{\fill}\hspace{\tabcolsep}} l r r r }
    \hline
    \bfseries Description of Services & \multicolumn{1}{c}{\bfseries Quantity} & \multicolumn{1}{c}{\bfseries Unit Price} & \multicolumn{1}{c}{\bfseries Amount} \\*
    \hline\hline
    \endhead
}{
    \hline\hline\hline
    \bfseries Balance Due & & & \bfseries \$\total{\totalcost} \\
    \end{longtable}
}
@pmcharrison

This comment has been minimized.

Copy link

commented Jul 5, 2017

eg9's solution worked great for me, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.