7.0pt ≠ x⋅10.0pt for all x












15















Consider the following input:



documentclass{article}
begin{document}
newlength{smallertopskip}
setlength{smallertopskip}{.700004577636718749999999999999999999999999999999topskip}
newlength{largertopskip}
setlength{largertopskip}{.700004577636718750000000000000000000000000000000topskip}

Topskip: thetopskip

Smaller: thesmallertopskip

Larger: thelargertopskip
end{document}


Running pdflatex on it results in




Topskip: 10.0pt



Smaller: 6.99997pt



Larger: 7.00012pt




As you see above, I tried hard to get exactly 7pt as a result of multiplication of some fixed-point constant with topskip, but failed. Sure, it's very well-known that fixed-point computations are really inaccurate in TeX, but I'm wondering whether some external package could provide us with a rather general-purpose multiplication function (say, mult) that is more precise than the built-in multiplication such that



newlength{myLength}
setlength{myLength}{mult{x}{topskip}}
themyLength


(or similar code) would result in 7.0pt for some verbatim fixed-point constant x assuming that topskip is 10.0pt? Notice that both 7.0 and 10.0 are representable in binary, and the mathematically correct answer x=7/10=0.7 is not representable in binary, but the fixed-point arithmetics is different anyway...



Aside: As some answers and comments notice, the difference between the under- and overapproximation is invisible to the naked eye. But the difference has an effect on potential further computations with myLength, including choosing, e.g., a font size (which is a non-continuous operation).










share|improve this question




















  • 12





    To achieve exact results on any system, TeX does not use floating-point at all for lengths. It does everything with integer units of sp, where 1 pt equals 65536 sp. (Another way of saying it is that it uses fixed-point arithmetic.) Your 10 pt corresponds to 655360 sp, your smallertopskip to 458750 sp, and your largertopskip to 458760 sp. (And your desired “target” 7 pt corresponds to 458752 sp.) Knuth regrets using binary instead of decimal here, probably because it leads to confusion like this.

    – ShreevatsaR
    Feb 7 at 4:55








  • 7





    You wrote, "Sure, it's very well-known that floating-point computations are really inaccurate in TeX." Actually, TeX does not use floating-point arithmetic, for reasons that have been noted many years ago -- by Knuth himself, as well as by others. Instead, as @ShreevatsaR has already point out in a comment, TeX uses fixed-point arithmetic. A separate comment: Are you concerned that there might be a meaningful, i.e., visually observable, difference between 6.9997pt and 7.00012pt? Please clarify.

    – Mico
    Feb 7 at 5:39








  • 1





    (Since I realized an ambiguity in my first comment) Using decimal instead of binary won't change the mathematics (with bounded memory you can have only limited precision), but just makes the human experience easier: e.g. instead of having fractions that are multiples of 1/65536 if you had say 1/10000 or 1/100000, then instead of 0.70000457763671875 being an interesting bound (it's halfway between two representable numbers 45875/65536 = 0.6999969482421875 and 45876/65536 = 0.70001220703125), some consecutive representable numbers may be (say) 0.69999, 0.70000, 0.70001 -- easier to understand.

    – ShreevatsaR
    Feb 7 at 18:38






  • 1





    @Mico You are right, technically speaking, it is fixed point. Corrected. As for the visible difference, there is one under magnification of 300%–400% (some further rounding happens down the pipe when myLength is used, which does result in a visible diffirence). For me, the differences accumulate so that in a large book which uses myLength inside some macro that is used at many places, tiny changes in myLength result in, e.g., changes in the page numbers of (sub)sections, and hence, the table of contents is different depending on whether you under- or overapproximate 7.0pt.

    – user49915
    Feb 7 at 18:47








  • 1





    @ShreevatsaR Ok. Frankly, it doesn't matter that much to me whether a decimal or a binary system is used internally.

    – user49915
    Feb 7 at 18:49


















15















Consider the following input:



documentclass{article}
begin{document}
newlength{smallertopskip}
setlength{smallertopskip}{.700004577636718749999999999999999999999999999999topskip}
newlength{largertopskip}
setlength{largertopskip}{.700004577636718750000000000000000000000000000000topskip}

Topskip: thetopskip

Smaller: thesmallertopskip

Larger: thelargertopskip
end{document}


Running pdflatex on it results in




Topskip: 10.0pt



Smaller: 6.99997pt



Larger: 7.00012pt




As you see above, I tried hard to get exactly 7pt as a result of multiplication of some fixed-point constant with topskip, but failed. Sure, it's very well-known that fixed-point computations are really inaccurate in TeX, but I'm wondering whether some external package could provide us with a rather general-purpose multiplication function (say, mult) that is more precise than the built-in multiplication such that



newlength{myLength}
setlength{myLength}{mult{x}{topskip}}
themyLength


(or similar code) would result in 7.0pt for some verbatim fixed-point constant x assuming that topskip is 10.0pt? Notice that both 7.0 and 10.0 are representable in binary, and the mathematically correct answer x=7/10=0.7 is not representable in binary, but the fixed-point arithmetics is different anyway...



Aside: As some answers and comments notice, the difference between the under- and overapproximation is invisible to the naked eye. But the difference has an effect on potential further computations with myLength, including choosing, e.g., a font size (which is a non-continuous operation).










share|improve this question




















  • 12





    To achieve exact results on any system, TeX does not use floating-point at all for lengths. It does everything with integer units of sp, where 1 pt equals 65536 sp. (Another way of saying it is that it uses fixed-point arithmetic.) Your 10 pt corresponds to 655360 sp, your smallertopskip to 458750 sp, and your largertopskip to 458760 sp. (And your desired “target” 7 pt corresponds to 458752 sp.) Knuth regrets using binary instead of decimal here, probably because it leads to confusion like this.

    – ShreevatsaR
    Feb 7 at 4:55








  • 7





    You wrote, "Sure, it's very well-known that floating-point computations are really inaccurate in TeX." Actually, TeX does not use floating-point arithmetic, for reasons that have been noted many years ago -- by Knuth himself, as well as by others. Instead, as @ShreevatsaR has already point out in a comment, TeX uses fixed-point arithmetic. A separate comment: Are you concerned that there might be a meaningful, i.e., visually observable, difference between 6.9997pt and 7.00012pt? Please clarify.

    – Mico
    Feb 7 at 5:39








  • 1





    (Since I realized an ambiguity in my first comment) Using decimal instead of binary won't change the mathematics (with bounded memory you can have only limited precision), but just makes the human experience easier: e.g. instead of having fractions that are multiples of 1/65536 if you had say 1/10000 or 1/100000, then instead of 0.70000457763671875 being an interesting bound (it's halfway between two representable numbers 45875/65536 = 0.6999969482421875 and 45876/65536 = 0.70001220703125), some consecutive representable numbers may be (say) 0.69999, 0.70000, 0.70001 -- easier to understand.

    – ShreevatsaR
    Feb 7 at 18:38






  • 1





    @Mico You are right, technically speaking, it is fixed point. Corrected. As for the visible difference, there is one under magnification of 300%–400% (some further rounding happens down the pipe when myLength is used, which does result in a visible diffirence). For me, the differences accumulate so that in a large book which uses myLength inside some macro that is used at many places, tiny changes in myLength result in, e.g., changes in the page numbers of (sub)sections, and hence, the table of contents is different depending on whether you under- or overapproximate 7.0pt.

    – user49915
    Feb 7 at 18:47








  • 1





    @ShreevatsaR Ok. Frankly, it doesn't matter that much to me whether a decimal or a binary system is used internally.

    – user49915
    Feb 7 at 18:49
















15












15








15


2






Consider the following input:



documentclass{article}
begin{document}
newlength{smallertopskip}
setlength{smallertopskip}{.700004577636718749999999999999999999999999999999topskip}
newlength{largertopskip}
setlength{largertopskip}{.700004577636718750000000000000000000000000000000topskip}

Topskip: thetopskip

Smaller: thesmallertopskip

Larger: thelargertopskip
end{document}


Running pdflatex on it results in




Topskip: 10.0pt



Smaller: 6.99997pt



Larger: 7.00012pt




As you see above, I tried hard to get exactly 7pt as a result of multiplication of some fixed-point constant with topskip, but failed. Sure, it's very well-known that fixed-point computations are really inaccurate in TeX, but I'm wondering whether some external package could provide us with a rather general-purpose multiplication function (say, mult) that is more precise than the built-in multiplication such that



newlength{myLength}
setlength{myLength}{mult{x}{topskip}}
themyLength


(or similar code) would result in 7.0pt for some verbatim fixed-point constant x assuming that topskip is 10.0pt? Notice that both 7.0 and 10.0 are representable in binary, and the mathematically correct answer x=7/10=0.7 is not representable in binary, but the fixed-point arithmetics is different anyway...



Aside: As some answers and comments notice, the difference between the under- and overapproximation is invisible to the naked eye. But the difference has an effect on potential further computations with myLength, including choosing, e.g., a font size (which is a non-continuous operation).










share|improve this question
















Consider the following input:



documentclass{article}
begin{document}
newlength{smallertopskip}
setlength{smallertopskip}{.700004577636718749999999999999999999999999999999topskip}
newlength{largertopskip}
setlength{largertopskip}{.700004577636718750000000000000000000000000000000topskip}

Topskip: thetopskip

Smaller: thesmallertopskip

Larger: thelargertopskip
end{document}


Running pdflatex on it results in




Topskip: 10.0pt



Smaller: 6.99997pt



Larger: 7.00012pt




As you see above, I tried hard to get exactly 7pt as a result of multiplication of some fixed-point constant with topskip, but failed. Sure, it's very well-known that fixed-point computations are really inaccurate in TeX, but I'm wondering whether some external package could provide us with a rather general-purpose multiplication function (say, mult) that is more precise than the built-in multiplication such that



newlength{myLength}
setlength{myLength}{mult{x}{topskip}}
themyLength


(or similar code) would result in 7.0pt for some verbatim fixed-point constant x assuming that topskip is 10.0pt? Notice that both 7.0 and 10.0 are representable in binary, and the mathematically correct answer x=7/10=0.7 is not representable in binary, but the fixed-point arithmetics is different anyway...



Aside: As some answers and comments notice, the difference between the under- and overapproximation is invisible to the naked eye. But the difference has an effect on potential further computations with myLength, including choosing, e.g., a font size (which is a non-continuous operation).







lengths arithmetic






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 8 at 1:29







user49915

















asked Feb 7 at 3:46









user49915user49915

682122




682122








  • 12





    To achieve exact results on any system, TeX does not use floating-point at all for lengths. It does everything with integer units of sp, where 1 pt equals 65536 sp. (Another way of saying it is that it uses fixed-point arithmetic.) Your 10 pt corresponds to 655360 sp, your smallertopskip to 458750 sp, and your largertopskip to 458760 sp. (And your desired “target” 7 pt corresponds to 458752 sp.) Knuth regrets using binary instead of decimal here, probably because it leads to confusion like this.

    – ShreevatsaR
    Feb 7 at 4:55








  • 7





    You wrote, "Sure, it's very well-known that floating-point computations are really inaccurate in TeX." Actually, TeX does not use floating-point arithmetic, for reasons that have been noted many years ago -- by Knuth himself, as well as by others. Instead, as @ShreevatsaR has already point out in a comment, TeX uses fixed-point arithmetic. A separate comment: Are you concerned that there might be a meaningful, i.e., visually observable, difference between 6.9997pt and 7.00012pt? Please clarify.

    – Mico
    Feb 7 at 5:39








  • 1





    (Since I realized an ambiguity in my first comment) Using decimal instead of binary won't change the mathematics (with bounded memory you can have only limited precision), but just makes the human experience easier: e.g. instead of having fractions that are multiples of 1/65536 if you had say 1/10000 or 1/100000, then instead of 0.70000457763671875 being an interesting bound (it's halfway between two representable numbers 45875/65536 = 0.6999969482421875 and 45876/65536 = 0.70001220703125), some consecutive representable numbers may be (say) 0.69999, 0.70000, 0.70001 -- easier to understand.

    – ShreevatsaR
    Feb 7 at 18:38






  • 1





    @Mico You are right, technically speaking, it is fixed point. Corrected. As for the visible difference, there is one under magnification of 300%–400% (some further rounding happens down the pipe when myLength is used, which does result in a visible diffirence). For me, the differences accumulate so that in a large book which uses myLength inside some macro that is used at many places, tiny changes in myLength result in, e.g., changes in the page numbers of (sub)sections, and hence, the table of contents is different depending on whether you under- or overapproximate 7.0pt.

    – user49915
    Feb 7 at 18:47








  • 1





    @ShreevatsaR Ok. Frankly, it doesn't matter that much to me whether a decimal or a binary system is used internally.

    – user49915
    Feb 7 at 18:49
















  • 12





    To achieve exact results on any system, TeX does not use floating-point at all for lengths. It does everything with integer units of sp, where 1 pt equals 65536 sp. (Another way of saying it is that it uses fixed-point arithmetic.) Your 10 pt corresponds to 655360 sp, your smallertopskip to 458750 sp, and your largertopskip to 458760 sp. (And your desired “target” 7 pt corresponds to 458752 sp.) Knuth regrets using binary instead of decimal here, probably because it leads to confusion like this.

    – ShreevatsaR
    Feb 7 at 4:55








  • 7





    You wrote, "Sure, it's very well-known that floating-point computations are really inaccurate in TeX." Actually, TeX does not use floating-point arithmetic, for reasons that have been noted many years ago -- by Knuth himself, as well as by others. Instead, as @ShreevatsaR has already point out in a comment, TeX uses fixed-point arithmetic. A separate comment: Are you concerned that there might be a meaningful, i.e., visually observable, difference between 6.9997pt and 7.00012pt? Please clarify.

    – Mico
    Feb 7 at 5:39








  • 1





    (Since I realized an ambiguity in my first comment) Using decimal instead of binary won't change the mathematics (with bounded memory you can have only limited precision), but just makes the human experience easier: e.g. instead of having fractions that are multiples of 1/65536 if you had say 1/10000 or 1/100000, then instead of 0.70000457763671875 being an interesting bound (it's halfway between two representable numbers 45875/65536 = 0.6999969482421875 and 45876/65536 = 0.70001220703125), some consecutive representable numbers may be (say) 0.69999, 0.70000, 0.70001 -- easier to understand.

    – ShreevatsaR
    Feb 7 at 18:38






  • 1





    @Mico You are right, technically speaking, it is fixed point. Corrected. As for the visible difference, there is one under magnification of 300%–400% (some further rounding happens down the pipe when myLength is used, which does result in a visible diffirence). For me, the differences accumulate so that in a large book which uses myLength inside some macro that is used at many places, tiny changes in myLength result in, e.g., changes in the page numbers of (sub)sections, and hence, the table of contents is different depending on whether you under- or overapproximate 7.0pt.

    – user49915
    Feb 7 at 18:47








  • 1





    @ShreevatsaR Ok. Frankly, it doesn't matter that much to me whether a decimal or a binary system is used internally.

    – user49915
    Feb 7 at 18:49










12




12





To achieve exact results on any system, TeX does not use floating-point at all for lengths. It does everything with integer units of sp, where 1 pt equals 65536 sp. (Another way of saying it is that it uses fixed-point arithmetic.) Your 10 pt corresponds to 655360 sp, your smallertopskip to 458750 sp, and your largertopskip to 458760 sp. (And your desired “target” 7 pt corresponds to 458752 sp.) Knuth regrets using binary instead of decimal here, probably because it leads to confusion like this.

– ShreevatsaR
Feb 7 at 4:55







To achieve exact results on any system, TeX does not use floating-point at all for lengths. It does everything with integer units of sp, where 1 pt equals 65536 sp. (Another way of saying it is that it uses fixed-point arithmetic.) Your 10 pt corresponds to 655360 sp, your smallertopskip to 458750 sp, and your largertopskip to 458760 sp. (And your desired “target” 7 pt corresponds to 458752 sp.) Knuth regrets using binary instead of decimal here, probably because it leads to confusion like this.

– ShreevatsaR
Feb 7 at 4:55






7




7





You wrote, "Sure, it's very well-known that floating-point computations are really inaccurate in TeX." Actually, TeX does not use floating-point arithmetic, for reasons that have been noted many years ago -- by Knuth himself, as well as by others. Instead, as @ShreevatsaR has already point out in a comment, TeX uses fixed-point arithmetic. A separate comment: Are you concerned that there might be a meaningful, i.e., visually observable, difference between 6.9997pt and 7.00012pt? Please clarify.

– Mico
Feb 7 at 5:39







You wrote, "Sure, it's very well-known that floating-point computations are really inaccurate in TeX." Actually, TeX does not use floating-point arithmetic, for reasons that have been noted many years ago -- by Knuth himself, as well as by others. Instead, as @ShreevatsaR has already point out in a comment, TeX uses fixed-point arithmetic. A separate comment: Are you concerned that there might be a meaningful, i.e., visually observable, difference between 6.9997pt and 7.00012pt? Please clarify.

– Mico
Feb 7 at 5:39






1




1





(Since I realized an ambiguity in my first comment) Using decimal instead of binary won't change the mathematics (with bounded memory you can have only limited precision), but just makes the human experience easier: e.g. instead of having fractions that are multiples of 1/65536 if you had say 1/10000 or 1/100000, then instead of 0.70000457763671875 being an interesting bound (it's halfway between two representable numbers 45875/65536 = 0.6999969482421875 and 45876/65536 = 0.70001220703125), some consecutive representable numbers may be (say) 0.69999, 0.70000, 0.70001 -- easier to understand.

– ShreevatsaR
Feb 7 at 18:38





(Since I realized an ambiguity in my first comment) Using decimal instead of binary won't change the mathematics (with bounded memory you can have only limited precision), but just makes the human experience easier: e.g. instead of having fractions that are multiples of 1/65536 if you had say 1/10000 or 1/100000, then instead of 0.70000457763671875 being an interesting bound (it's halfway between two representable numbers 45875/65536 = 0.6999969482421875 and 45876/65536 = 0.70001220703125), some consecutive representable numbers may be (say) 0.69999, 0.70000, 0.70001 -- easier to understand.

– ShreevatsaR
Feb 7 at 18:38




1




1





@Mico You are right, technically speaking, it is fixed point. Corrected. As for the visible difference, there is one under magnification of 300%–400% (some further rounding happens down the pipe when myLength is used, which does result in a visible diffirence). For me, the differences accumulate so that in a large book which uses myLength inside some macro that is used at many places, tiny changes in myLength result in, e.g., changes in the page numbers of (sub)sections, and hence, the table of contents is different depending on whether you under- or overapproximate 7.0pt.

– user49915
Feb 7 at 18:47







@Mico You are right, technically speaking, it is fixed point. Corrected. As for the visible difference, there is one under magnification of 300%–400% (some further rounding happens down the pipe when myLength is used, which does result in a visible diffirence). For me, the differences accumulate so that in a large book which uses myLength inside some macro that is used at many places, tiny changes in myLength result in, e.g., changes in the page numbers of (sub)sections, and hence, the table of contents is different depending on whether you under- or overapproximate 7.0pt.

– user49915
Feb 7 at 18:47






1




1





@ShreevatsaR Ok. Frankly, it doesn't matter that much to me whether a decimal or a binary system is used internally.

– user49915
Feb 7 at 18:49







@ShreevatsaR Ok. Frankly, it doesn't matter that much to me whether a decimal or a binary system is used internally.

– user49915
Feb 7 at 18:49












4 Answers
4






active

oldest

votes


















19














It's not really that TeX floating point calculations are inaccurate, it simply isn't doing floating point at all, so you either need a macro implementation such as the xfp package in Werner's answer, or suitably scale the calculation so that it is accurate in the range of fixed point arithmetic being used by TeX and using integer quantities that can be stored exactly (as opposed to 0.7) also helps.



documentclass{article}

begin{document}
newlength{smallertopskip}
setlength{smallertopskip}{dimexpr 7topskip/10relax}

Topskip: thetopskip

Smaller: thesmallertopskip


end{document}


enter image description here



Although it only really makes a difference in this special case that the value is a known integer. In general, if you are going to need decimal places in the answer just rounding to 1 or two decimal places will ensure a consistent result and not make any real difference to the output, .000001pt isn't very big.






share|improve this answer
























  • That's probably better than loading thousands of lines of expl3 macros.

    – Henri Menke
    Feb 7 at 8:07











  • @HenriMenke yes but if you know you want a zero decimal places answer it's easy to arrange an integer answer, if you want 75% of 11pt, then perhaps less so, it depends why you are worrying about a +/-.00001 pt difference I suppose.

    – David Carlisle
    Feb 7 at 11:42











  • Thx! Regarding .000001pt: Alone, this difference is invisible. But it does get visible whenever there is further processing and rounding down the pipe (e.g., when choosing a font size depending on some computations with myLength). Moreover, GuM said that topskip is a <glue parameter>, not a <dimen parameter>, so using glueexpr might hypothetically be more accurate than using dimexpr.

    – user49915
    Feb 7 at 19:39











  • @user0 you need an awful lot of rounding to make that visible, it really isn't ever going to happen. How many further calculations are you ever going to do with topskip? and dimexpr and gluexpr are the same here as the form <factor><glue> discards the stretch and shrink components anyway.

    – David Carlisle
    Feb 7 at 20:11








  • 1





    @user0 yes that's why I constructed the arithmetic as I did in this answer, keeping all intermediate steps exactly representable *7 divide 10 rather than multiply by 0.7

    – David Carlisle
    Feb 7 at 20:48



















18














Use xfp:




7.0pt




documentclass{article}

usepackage{xfp}

begin{document}

newlength{myLength}%
setlength{myLength}{fpeval{round(0.7 * topskip, 0)}pt}%
themyLength

end{document}


Dimensions in fpeval are converted to pt and stripped of the dimension part in order to perform calculations (hence the addition of a "closing pt").



If you want you can define



newcommand{mult}[2]{fpeval{round(#1 * #2, 0)}pt}


to support your input



setlength{myLength}{mult{0.7}{topskip}}





share|improve this answer
























  • Thanks! Your mult contains, I guess, rounding, so is it really more precise than the built-in TeX multiplication?

    – user49915
    Feb 7 at 5:14













  • @user0: It may counter the errors that could result from floating point computations.

    – Werner
    Feb 7 at 5:28






  • 1





    @user0 Of course, even with xfp (or any approach) once you assign to a length, you'll only get integer multiples of 1 sp (= 1/65536 pt), so this only affects the rounding that happens to 0.7 (or whatever) before the multiplication; it doesn't affect the range of possible values for the length at the end.

    – ShreevatsaR
    Feb 7 at 6:25








  • 4





    This looks like a quite complicated way to say setlength{mylenth}{7pt}.

    – Ulrike Fischer
    Feb 7 at 7:50






  • 2





    @user0 that was a joke. But I would use setlength{myLength}{fpeval{dim_to_decimal:n {topskip} * 0.7}pt} instead of rounding the result.

    – Ulrike Fischer
    Feb 7 at 19:12



















13














There is no way to get a length of 458752sp from <factor>topskip if topskip has the value 10pt, that is, 655360sp, because TeX don't do floating-point computations, but fixed-point base two arithmetic.1



The binary representation of 7/10 is 0.10(1100), parentheses denote the period. and the multiplication rules of TeX can only provide either 458750sp or 458760sp, represented respectively as 6.99997pt and 7.00012pt.



The difference between the upper and lower best representations is 10sp, which is less than 0.000435 millimeters or 0.00016 points.



Since the usual value of vfuzz is 0.1pt (less than 0.03mm), there should be no concern about getting an “exact” value: you'd need to cumulate more than 680 such errors in order to exceed the vfuzz.



documentclass{article}

newlength{multipletopskip}

begin{document}

Topskip: thetopskip (numbertopskip sp)

70% topskip: thedimexpr 7topskip/10relax (numberdimexpr 7topskip/10relax sp)

setlength{multipletopskip}{0.7topskip}
0.7 topskip: themultipletopskip (numbermultipletopskip sp)

setlength{multipletopskip}{0.70001topskip}
0.70001 topskip: themultipletopskip (numbermultipletopskip sp)

end{document}


As you see, 0.7topskip is accurate up to 2sp, less than 0.00009mm.2



Unless you completely override TeX's computation by using a different model such as IEEE754 (decimal32) as is done in Werner's answer, you can't get “exact” values.





Footnotes



1 When TeX was written, there was no agreed upon standard for floating-point computations and Knuth's aim was to obtain the same output on every machine TeX was implemented on. Using 64 bits instead of 32 could have achieved “better” accuracy, but at the expense of speed and need for memory: PC's of that time might have even less than 640 kiB of RAM.



2 Being a skip, it would be more sensible to use glueexpr rather than dimexpr, as noted by GuM in comments. Note that <factor><skip register> will discard the plus and minus components, whereas multiply and divide don't. So



setlength{multipletopskip}{glueexprtopskip*7/10relax}


could be better.






share|improve this answer





















  • 2





    In fact, how tiny these differences are becomes clearer when we switch to small units: a difference of 10 sp is about 53 nanometres. As The TeXbook says “Since the wavelength of visible light is approximately 100 sp, [DEK adds comment in texbook.tex: in fact, violet=75sp, red=135sp] rounding errors of a few sp make no difference to the eye”.

    – ShreevatsaR
    Feb 7 at 12:49











  • Don't you mean 0.1pt is approx. 0.03mm, not 0.3mm? 0.3mm is about 1/3 of a mm, which is about 1/75 of an inch, which is about 1pt not 0.1pt.

    – alephzero
    Feb 7 at 16:09






  • 1





    This answer contains the implicit remark that eTeX’s dimexpr (or glueexpr) provides better precision: why not to make this remark explicit?

    – GuM
    Feb 7 at 18:59






  • 1





    @user0: I don’t think it is a good idea to allow the topskip glue to stretch or shrink; nonetheless, Knuth decided to make topskip a <glue parameter>, not a <dimen parameter>, so, in the principle, using glueexpr should be safer (and more elegant). It depends, however, on what you are trying to achieve: you may well want to kill tpskip’s shrinkability/stretchability intentionally.

    – GuM
    Feb 7 at 19:15








  • 1





    @user0 7topskip discards the stretch, if you don't want to do that use setlength{myLengthG}{glueexprtopskip*7/10relax}

    – David Carlisle
    Feb 7 at 20:15



















2














This should not be an answer, but rather a comment both to @egreg’s answer and to David Carlisle’s; unfortunately, I need to include some sample code, and this can only be done (in an intelligible form) in an answer. I willingly concede that it doesn’t add anything substantial to those two answers—except, perhaps, a bit of clarity. I’m ready to remove this answer if either of the abovementioned authors clarifies his.



As already repeatedly remarked, Knuth’s TeX does (or rather, did) its calculations with dimensions using 32-bit fixed points arithmetics; all modern typesetting engines, however, incorporate the so-called “e-TeX” (for Extended, or Enhanced, TeX) extensions, among which is the ability to perform dimension scaling, that is, multiplication of a dimension for a fraction, with 64-bit precision. More precisely, e-TeX extensions introduce a new type of syntax by means of which dimensions can be specified, that enables the use of “expressions”, in the customary sense of the term; in particular, you are allowed to multiply a certain dimension for a fraction, as in



setlengthsomeotherdimen{dimexpr somedimen * 7/10}


(the primitive dimexpr marks the beginning of a “dimen-valued” expression; the end is implicitly marked by the first token that cannot be interpreted as part of the expression itself—you can assume it is the closing brace, in the above example). When this is done, a 64-bit temporary register is used to hold the intermediate result of the multiplication of the dimension for the numerator of the fraction (somedimen * 7, in the above example); thank to this expedient, when the subsequent division for the denominator (10, in our case) is performed, all bits of the final (32-bit) result are significant.



As already said, dimexpr starts a “dimen-valued” expression; there exists a similar primitive for “glue-valued” expressions, named glueexpr. Note, however, the difference, that others have already explained, between



setlengthsomeotherskip{glueexpr 7someskip /10}


and



setlengthsomeotherskip{glueexpr someskip * 7/10}


In the former, 7someskip is converted to a dimen value, destroying (that is, zeroing) its stretch and shrink components, if any; this doesn’t happen with the latter.



The following code proves that



setlength{someotherskip}{glueexpr topskip * 7/10}


attains the same precision as explicitly setting someotherskip to 7pt (and similarly for the stretch and shrink components, if present):



% My standard header for TeX.SX answers:
documentclass[a4paper]{article} % To avoid confusion, let us explicitly
% declare the paper format.

usepackage[T1]{fontenc} % Not always necessary, but recommended.
% End of standard header. What follows pertains to the problem at hand.

newcommand*{ReportDimen}[2]{%
#1:>texttt{the #2}\>texttt{(number #2sp)}\%
}
newcommand*{ReportGlue}[2]{%
#1:>texttt{the #2}\>%
texttt{(%
number #2sp
plus numberexpandafterdimexprthegluestretch #2relax sp
minus numberexpandafterdimexprtheglueshrink #2relax sp%
)}\%
}

setlength{topskip}{10.0pt plus 1pt minus 1 pt}
newlength{smallertopskip}
setlength{smallertopskip}{.700004577636718749999999999999999999999999999999topskip}
newlength{largertopskip}
setlength{largertopskip}{.700004577636718750000000000000000000000000000000topskip}
newlength{eTeXTopskip}
setlength{eTeXTopskip}{glueexpr topskip * 7/10}
newlength{sevenpoints}
setlength{sevenpoints}{7.0pt plus .7pt minus .7pt}



begin{document}

begin{tabbing}
Topskip:quad=kill
ReportGlue {Topskip}{topskip}
ReportDimen{Smaller}{smallertopskip}
ReportDimen{Larger}{largertopskip}
ReportGlue {eTeX's}{eTeXTopskip}
ReportGlue {Exact}{sevenpoints}
end{tabbing}

end{document}


(values in scaled points are shown as well).






share|improve this answer


























    Your Answer








    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "85"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f473706%2f7-0pt-%25e2%2589%25a0-x%25e2%258b%258510-0pt-for-all-x%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    19














    It's not really that TeX floating point calculations are inaccurate, it simply isn't doing floating point at all, so you either need a macro implementation such as the xfp package in Werner's answer, or suitably scale the calculation so that it is accurate in the range of fixed point arithmetic being used by TeX and using integer quantities that can be stored exactly (as opposed to 0.7) also helps.



    documentclass{article}

    begin{document}
    newlength{smallertopskip}
    setlength{smallertopskip}{dimexpr 7topskip/10relax}

    Topskip: thetopskip

    Smaller: thesmallertopskip


    end{document}


    enter image description here



    Although it only really makes a difference in this special case that the value is a known integer. In general, if you are going to need decimal places in the answer just rounding to 1 or two decimal places will ensure a consistent result and not make any real difference to the output, .000001pt isn't very big.






    share|improve this answer
























    • That's probably better than loading thousands of lines of expl3 macros.

      – Henri Menke
      Feb 7 at 8:07











    • @HenriMenke yes but if you know you want a zero decimal places answer it's easy to arrange an integer answer, if you want 75% of 11pt, then perhaps less so, it depends why you are worrying about a +/-.00001 pt difference I suppose.

      – David Carlisle
      Feb 7 at 11:42











    • Thx! Regarding .000001pt: Alone, this difference is invisible. But it does get visible whenever there is further processing and rounding down the pipe (e.g., when choosing a font size depending on some computations with myLength). Moreover, GuM said that topskip is a <glue parameter>, not a <dimen parameter>, so using glueexpr might hypothetically be more accurate than using dimexpr.

      – user49915
      Feb 7 at 19:39











    • @user0 you need an awful lot of rounding to make that visible, it really isn't ever going to happen. How many further calculations are you ever going to do with topskip? and dimexpr and gluexpr are the same here as the form <factor><glue> discards the stretch and shrink components anyway.

      – David Carlisle
      Feb 7 at 20:11








    • 1





      @user0 yes that's why I constructed the arithmetic as I did in this answer, keeping all intermediate steps exactly representable *7 divide 10 rather than multiply by 0.7

      – David Carlisle
      Feb 7 at 20:48
















    19














    It's not really that TeX floating point calculations are inaccurate, it simply isn't doing floating point at all, so you either need a macro implementation such as the xfp package in Werner's answer, or suitably scale the calculation so that it is accurate in the range of fixed point arithmetic being used by TeX and using integer quantities that can be stored exactly (as opposed to 0.7) also helps.



    documentclass{article}

    begin{document}
    newlength{smallertopskip}
    setlength{smallertopskip}{dimexpr 7topskip/10relax}

    Topskip: thetopskip

    Smaller: thesmallertopskip


    end{document}


    enter image description here



    Although it only really makes a difference in this special case that the value is a known integer. In general, if you are going to need decimal places in the answer just rounding to 1 or two decimal places will ensure a consistent result and not make any real difference to the output, .000001pt isn't very big.






    share|improve this answer
























    • That's probably better than loading thousands of lines of expl3 macros.

      – Henri Menke
      Feb 7 at 8:07











    • @HenriMenke yes but if you know you want a zero decimal places answer it's easy to arrange an integer answer, if you want 75% of 11pt, then perhaps less so, it depends why you are worrying about a +/-.00001 pt difference I suppose.

      – David Carlisle
      Feb 7 at 11:42











    • Thx! Regarding .000001pt: Alone, this difference is invisible. But it does get visible whenever there is further processing and rounding down the pipe (e.g., when choosing a font size depending on some computations with myLength). Moreover, GuM said that topskip is a <glue parameter>, not a <dimen parameter>, so using glueexpr might hypothetically be more accurate than using dimexpr.

      – user49915
      Feb 7 at 19:39











    • @user0 you need an awful lot of rounding to make that visible, it really isn't ever going to happen. How many further calculations are you ever going to do with topskip? and dimexpr and gluexpr are the same here as the form <factor><glue> discards the stretch and shrink components anyway.

      – David Carlisle
      Feb 7 at 20:11








    • 1





      @user0 yes that's why I constructed the arithmetic as I did in this answer, keeping all intermediate steps exactly representable *7 divide 10 rather than multiply by 0.7

      – David Carlisle
      Feb 7 at 20:48














    19












    19








    19







    It's not really that TeX floating point calculations are inaccurate, it simply isn't doing floating point at all, so you either need a macro implementation such as the xfp package in Werner's answer, or suitably scale the calculation so that it is accurate in the range of fixed point arithmetic being used by TeX and using integer quantities that can be stored exactly (as opposed to 0.7) also helps.



    documentclass{article}

    begin{document}
    newlength{smallertopskip}
    setlength{smallertopskip}{dimexpr 7topskip/10relax}

    Topskip: thetopskip

    Smaller: thesmallertopskip


    end{document}


    enter image description here



    Although it only really makes a difference in this special case that the value is a known integer. In general, if you are going to need decimal places in the answer just rounding to 1 or two decimal places will ensure a consistent result and not make any real difference to the output, .000001pt isn't very big.






    share|improve this answer













    It's not really that TeX floating point calculations are inaccurate, it simply isn't doing floating point at all, so you either need a macro implementation such as the xfp package in Werner's answer, or suitably scale the calculation so that it is accurate in the range of fixed point arithmetic being used by TeX and using integer quantities that can be stored exactly (as opposed to 0.7) also helps.



    documentclass{article}

    begin{document}
    newlength{smallertopskip}
    setlength{smallertopskip}{dimexpr 7topskip/10relax}

    Topskip: thetopskip

    Smaller: thesmallertopskip


    end{document}


    enter image description here



    Although it only really makes a difference in this special case that the value is a known integer. In general, if you are going to need decimal places in the answer just rounding to 1 or two decimal places will ensure a consistent result and not make any real difference to the output, .000001pt isn't very big.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Feb 7 at 7:54









    David CarlisleDavid Carlisle

    496k4111441890




    496k4111441890













    • That's probably better than loading thousands of lines of expl3 macros.

      – Henri Menke
      Feb 7 at 8:07











    • @HenriMenke yes but if you know you want a zero decimal places answer it's easy to arrange an integer answer, if you want 75% of 11pt, then perhaps less so, it depends why you are worrying about a +/-.00001 pt difference I suppose.

      – David Carlisle
      Feb 7 at 11:42











    • Thx! Regarding .000001pt: Alone, this difference is invisible. But it does get visible whenever there is further processing and rounding down the pipe (e.g., when choosing a font size depending on some computations with myLength). Moreover, GuM said that topskip is a <glue parameter>, not a <dimen parameter>, so using glueexpr might hypothetically be more accurate than using dimexpr.

      – user49915
      Feb 7 at 19:39











    • @user0 you need an awful lot of rounding to make that visible, it really isn't ever going to happen. How many further calculations are you ever going to do with topskip? and dimexpr and gluexpr are the same here as the form <factor><glue> discards the stretch and shrink components anyway.

      – David Carlisle
      Feb 7 at 20:11








    • 1





      @user0 yes that's why I constructed the arithmetic as I did in this answer, keeping all intermediate steps exactly representable *7 divide 10 rather than multiply by 0.7

      – David Carlisle
      Feb 7 at 20:48



















    • That's probably better than loading thousands of lines of expl3 macros.

      – Henri Menke
      Feb 7 at 8:07











    • @HenriMenke yes but if you know you want a zero decimal places answer it's easy to arrange an integer answer, if you want 75% of 11pt, then perhaps less so, it depends why you are worrying about a +/-.00001 pt difference I suppose.

      – David Carlisle
      Feb 7 at 11:42











    • Thx! Regarding .000001pt: Alone, this difference is invisible. But it does get visible whenever there is further processing and rounding down the pipe (e.g., when choosing a font size depending on some computations with myLength). Moreover, GuM said that topskip is a <glue parameter>, not a <dimen parameter>, so using glueexpr might hypothetically be more accurate than using dimexpr.

      – user49915
      Feb 7 at 19:39











    • @user0 you need an awful lot of rounding to make that visible, it really isn't ever going to happen. How many further calculations are you ever going to do with topskip? and dimexpr and gluexpr are the same here as the form <factor><glue> discards the stretch and shrink components anyway.

      – David Carlisle
      Feb 7 at 20:11








    • 1





      @user0 yes that's why I constructed the arithmetic as I did in this answer, keeping all intermediate steps exactly representable *7 divide 10 rather than multiply by 0.7

      – David Carlisle
      Feb 7 at 20:48

















    That's probably better than loading thousands of lines of expl3 macros.

    – Henri Menke
    Feb 7 at 8:07





    That's probably better than loading thousands of lines of expl3 macros.

    – Henri Menke
    Feb 7 at 8:07













    @HenriMenke yes but if you know you want a zero decimal places answer it's easy to arrange an integer answer, if you want 75% of 11pt, then perhaps less so, it depends why you are worrying about a +/-.00001 pt difference I suppose.

    – David Carlisle
    Feb 7 at 11:42





    @HenriMenke yes but if you know you want a zero decimal places answer it's easy to arrange an integer answer, if you want 75% of 11pt, then perhaps less so, it depends why you are worrying about a +/-.00001 pt difference I suppose.

    – David Carlisle
    Feb 7 at 11:42













    Thx! Regarding .000001pt: Alone, this difference is invisible. But it does get visible whenever there is further processing and rounding down the pipe (e.g., when choosing a font size depending on some computations with myLength). Moreover, GuM said that topskip is a <glue parameter>, not a <dimen parameter>, so using glueexpr might hypothetically be more accurate than using dimexpr.

    – user49915
    Feb 7 at 19:39





    Thx! Regarding .000001pt: Alone, this difference is invisible. But it does get visible whenever there is further processing and rounding down the pipe (e.g., when choosing a font size depending on some computations with myLength). Moreover, GuM said that topskip is a <glue parameter>, not a <dimen parameter>, so using glueexpr might hypothetically be more accurate than using dimexpr.

    – user49915
    Feb 7 at 19:39













    @user0 you need an awful lot of rounding to make that visible, it really isn't ever going to happen. How many further calculations are you ever going to do with topskip? and dimexpr and gluexpr are the same here as the form <factor><glue> discards the stretch and shrink components anyway.

    – David Carlisle
    Feb 7 at 20:11







    @user0 you need an awful lot of rounding to make that visible, it really isn't ever going to happen. How many further calculations are you ever going to do with topskip? and dimexpr and gluexpr are the same here as the form <factor><glue> discards the stretch and shrink components anyway.

    – David Carlisle
    Feb 7 at 20:11






    1




    1





    @user0 yes that's why I constructed the arithmetic as I did in this answer, keeping all intermediate steps exactly representable *7 divide 10 rather than multiply by 0.7

    – David Carlisle
    Feb 7 at 20:48





    @user0 yes that's why I constructed the arithmetic as I did in this answer, keeping all intermediate steps exactly representable *7 divide 10 rather than multiply by 0.7

    – David Carlisle
    Feb 7 at 20:48











    18














    Use xfp:




    7.0pt




    documentclass{article}

    usepackage{xfp}

    begin{document}

    newlength{myLength}%
    setlength{myLength}{fpeval{round(0.7 * topskip, 0)}pt}%
    themyLength

    end{document}


    Dimensions in fpeval are converted to pt and stripped of the dimension part in order to perform calculations (hence the addition of a "closing pt").



    If you want you can define



    newcommand{mult}[2]{fpeval{round(#1 * #2, 0)}pt}


    to support your input



    setlength{myLength}{mult{0.7}{topskip}}





    share|improve this answer
























    • Thanks! Your mult contains, I guess, rounding, so is it really more precise than the built-in TeX multiplication?

      – user49915
      Feb 7 at 5:14













    • @user0: It may counter the errors that could result from floating point computations.

      – Werner
      Feb 7 at 5:28






    • 1





      @user0 Of course, even with xfp (or any approach) once you assign to a length, you'll only get integer multiples of 1 sp (= 1/65536 pt), so this only affects the rounding that happens to 0.7 (or whatever) before the multiplication; it doesn't affect the range of possible values for the length at the end.

      – ShreevatsaR
      Feb 7 at 6:25








    • 4





      This looks like a quite complicated way to say setlength{mylenth}{7pt}.

      – Ulrike Fischer
      Feb 7 at 7:50






    • 2





      @user0 that was a joke. But I would use setlength{myLength}{fpeval{dim_to_decimal:n {topskip} * 0.7}pt} instead of rounding the result.

      – Ulrike Fischer
      Feb 7 at 19:12
















    18














    Use xfp:




    7.0pt




    documentclass{article}

    usepackage{xfp}

    begin{document}

    newlength{myLength}%
    setlength{myLength}{fpeval{round(0.7 * topskip, 0)}pt}%
    themyLength

    end{document}


    Dimensions in fpeval are converted to pt and stripped of the dimension part in order to perform calculations (hence the addition of a "closing pt").



    If you want you can define



    newcommand{mult}[2]{fpeval{round(#1 * #2, 0)}pt}


    to support your input



    setlength{myLength}{mult{0.7}{topskip}}





    share|improve this answer
























    • Thanks! Your mult contains, I guess, rounding, so is it really more precise than the built-in TeX multiplication?

      – user49915
      Feb 7 at 5:14













    • @user0: It may counter the errors that could result from floating point computations.

      – Werner
      Feb 7 at 5:28






    • 1





      @user0 Of course, even with xfp (or any approach) once you assign to a length, you'll only get integer multiples of 1 sp (= 1/65536 pt), so this only affects the rounding that happens to 0.7 (or whatever) before the multiplication; it doesn't affect the range of possible values for the length at the end.

      – ShreevatsaR
      Feb 7 at 6:25








    • 4





      This looks like a quite complicated way to say setlength{mylenth}{7pt}.

      – Ulrike Fischer
      Feb 7 at 7:50






    • 2





      @user0 that was a joke. But I would use setlength{myLength}{fpeval{dim_to_decimal:n {topskip} * 0.7}pt} instead of rounding the result.

      – Ulrike Fischer
      Feb 7 at 19:12














    18












    18








    18







    Use xfp:




    7.0pt




    documentclass{article}

    usepackage{xfp}

    begin{document}

    newlength{myLength}%
    setlength{myLength}{fpeval{round(0.7 * topskip, 0)}pt}%
    themyLength

    end{document}


    Dimensions in fpeval are converted to pt and stripped of the dimension part in order to perform calculations (hence the addition of a "closing pt").



    If you want you can define



    newcommand{mult}[2]{fpeval{round(#1 * #2, 0)}pt}


    to support your input



    setlength{myLength}{mult{0.7}{topskip}}





    share|improve this answer













    Use xfp:




    7.0pt




    documentclass{article}

    usepackage{xfp}

    begin{document}

    newlength{myLength}%
    setlength{myLength}{fpeval{round(0.7 * topskip, 0)}pt}%
    themyLength

    end{document}


    Dimensions in fpeval are converted to pt and stripped of the dimension part in order to perform calculations (hence the addition of a "closing pt").



    If you want you can define



    newcommand{mult}[2]{fpeval{round(#1 * #2, 0)}pt}


    to support your input



    setlength{myLength}{mult{0.7}{topskip}}






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Feb 7 at 3:54









    WernerWerner

    449k729951700




    449k729951700













    • Thanks! Your mult contains, I guess, rounding, so is it really more precise than the built-in TeX multiplication?

      – user49915
      Feb 7 at 5:14













    • @user0: It may counter the errors that could result from floating point computations.

      – Werner
      Feb 7 at 5:28






    • 1





      @user0 Of course, even with xfp (or any approach) once you assign to a length, you'll only get integer multiples of 1 sp (= 1/65536 pt), so this only affects the rounding that happens to 0.7 (or whatever) before the multiplication; it doesn't affect the range of possible values for the length at the end.

      – ShreevatsaR
      Feb 7 at 6:25








    • 4





      This looks like a quite complicated way to say setlength{mylenth}{7pt}.

      – Ulrike Fischer
      Feb 7 at 7:50






    • 2





      @user0 that was a joke. But I would use setlength{myLength}{fpeval{dim_to_decimal:n {topskip} * 0.7}pt} instead of rounding the result.

      – Ulrike Fischer
      Feb 7 at 19:12



















    • Thanks! Your mult contains, I guess, rounding, so is it really more precise than the built-in TeX multiplication?

      – user49915
      Feb 7 at 5:14













    • @user0: It may counter the errors that could result from floating point computations.

      – Werner
      Feb 7 at 5:28






    • 1





      @user0 Of course, even with xfp (or any approach) once you assign to a length, you'll only get integer multiples of 1 sp (= 1/65536 pt), so this only affects the rounding that happens to 0.7 (or whatever) before the multiplication; it doesn't affect the range of possible values for the length at the end.

      – ShreevatsaR
      Feb 7 at 6:25








    • 4





      This looks like a quite complicated way to say setlength{mylenth}{7pt}.

      – Ulrike Fischer
      Feb 7 at 7:50






    • 2





      @user0 that was a joke. But I would use setlength{myLength}{fpeval{dim_to_decimal:n {topskip} * 0.7}pt} instead of rounding the result.

      – Ulrike Fischer
      Feb 7 at 19:12

















    Thanks! Your mult contains, I guess, rounding, so is it really more precise than the built-in TeX multiplication?

    – user49915
    Feb 7 at 5:14







    Thanks! Your mult contains, I guess, rounding, so is it really more precise than the built-in TeX multiplication?

    – user49915
    Feb 7 at 5:14















    @user0: It may counter the errors that could result from floating point computations.

    – Werner
    Feb 7 at 5:28





    @user0: It may counter the errors that could result from floating point computations.

    – Werner
    Feb 7 at 5:28




    1




    1





    @user0 Of course, even with xfp (or any approach) once you assign to a length, you'll only get integer multiples of 1 sp (= 1/65536 pt), so this only affects the rounding that happens to 0.7 (or whatever) before the multiplication; it doesn't affect the range of possible values for the length at the end.

    – ShreevatsaR
    Feb 7 at 6:25







    @user0 Of course, even with xfp (or any approach) once you assign to a length, you'll only get integer multiples of 1 sp (= 1/65536 pt), so this only affects the rounding that happens to 0.7 (or whatever) before the multiplication; it doesn't affect the range of possible values for the length at the end.

    – ShreevatsaR
    Feb 7 at 6:25






    4




    4





    This looks like a quite complicated way to say setlength{mylenth}{7pt}.

    – Ulrike Fischer
    Feb 7 at 7:50





    This looks like a quite complicated way to say setlength{mylenth}{7pt}.

    – Ulrike Fischer
    Feb 7 at 7:50




    2




    2





    @user0 that was a joke. But I would use setlength{myLength}{fpeval{dim_to_decimal:n {topskip} * 0.7}pt} instead of rounding the result.

    – Ulrike Fischer
    Feb 7 at 19:12





    @user0 that was a joke. But I would use setlength{myLength}{fpeval{dim_to_decimal:n {topskip} * 0.7}pt} instead of rounding the result.

    – Ulrike Fischer
    Feb 7 at 19:12











    13














    There is no way to get a length of 458752sp from <factor>topskip if topskip has the value 10pt, that is, 655360sp, because TeX don't do floating-point computations, but fixed-point base two arithmetic.1



    The binary representation of 7/10 is 0.10(1100), parentheses denote the period. and the multiplication rules of TeX can only provide either 458750sp or 458760sp, represented respectively as 6.99997pt and 7.00012pt.



    The difference between the upper and lower best representations is 10sp, which is less than 0.000435 millimeters or 0.00016 points.



    Since the usual value of vfuzz is 0.1pt (less than 0.03mm), there should be no concern about getting an “exact” value: you'd need to cumulate more than 680 such errors in order to exceed the vfuzz.



    documentclass{article}

    newlength{multipletopskip}

    begin{document}

    Topskip: thetopskip (numbertopskip sp)

    70% topskip: thedimexpr 7topskip/10relax (numberdimexpr 7topskip/10relax sp)

    setlength{multipletopskip}{0.7topskip}
    0.7 topskip: themultipletopskip (numbermultipletopskip sp)

    setlength{multipletopskip}{0.70001topskip}
    0.70001 topskip: themultipletopskip (numbermultipletopskip sp)

    end{document}


    As you see, 0.7topskip is accurate up to 2sp, less than 0.00009mm.2



    Unless you completely override TeX's computation by using a different model such as IEEE754 (decimal32) as is done in Werner's answer, you can't get “exact” values.





    Footnotes



    1 When TeX was written, there was no agreed upon standard for floating-point computations and Knuth's aim was to obtain the same output on every machine TeX was implemented on. Using 64 bits instead of 32 could have achieved “better” accuracy, but at the expense of speed and need for memory: PC's of that time might have even less than 640 kiB of RAM.



    2 Being a skip, it would be more sensible to use glueexpr rather than dimexpr, as noted by GuM in comments. Note that <factor><skip register> will discard the plus and minus components, whereas multiply and divide don't. So



    setlength{multipletopskip}{glueexprtopskip*7/10relax}


    could be better.






    share|improve this answer





















    • 2





      In fact, how tiny these differences are becomes clearer when we switch to small units: a difference of 10 sp is about 53 nanometres. As The TeXbook says “Since the wavelength of visible light is approximately 100 sp, [DEK adds comment in texbook.tex: in fact, violet=75sp, red=135sp] rounding errors of a few sp make no difference to the eye”.

      – ShreevatsaR
      Feb 7 at 12:49











    • Don't you mean 0.1pt is approx. 0.03mm, not 0.3mm? 0.3mm is about 1/3 of a mm, which is about 1/75 of an inch, which is about 1pt not 0.1pt.

      – alephzero
      Feb 7 at 16:09






    • 1





      This answer contains the implicit remark that eTeX’s dimexpr (or glueexpr) provides better precision: why not to make this remark explicit?

      – GuM
      Feb 7 at 18:59






    • 1





      @user0: I don’t think it is a good idea to allow the topskip glue to stretch or shrink; nonetheless, Knuth decided to make topskip a <glue parameter>, not a <dimen parameter>, so, in the principle, using glueexpr should be safer (and more elegant). It depends, however, on what you are trying to achieve: you may well want to kill tpskip’s shrinkability/stretchability intentionally.

      – GuM
      Feb 7 at 19:15








    • 1





      @user0 7topskip discards the stretch, if you don't want to do that use setlength{myLengthG}{glueexprtopskip*7/10relax}

      – David Carlisle
      Feb 7 at 20:15
















    13














    There is no way to get a length of 458752sp from <factor>topskip if topskip has the value 10pt, that is, 655360sp, because TeX don't do floating-point computations, but fixed-point base two arithmetic.1



    The binary representation of 7/10 is 0.10(1100), parentheses denote the period. and the multiplication rules of TeX can only provide either 458750sp or 458760sp, represented respectively as 6.99997pt and 7.00012pt.



    The difference between the upper and lower best representations is 10sp, which is less than 0.000435 millimeters or 0.00016 points.



    Since the usual value of vfuzz is 0.1pt (less than 0.03mm), there should be no concern about getting an “exact” value: you'd need to cumulate more than 680 such errors in order to exceed the vfuzz.



    documentclass{article}

    newlength{multipletopskip}

    begin{document}

    Topskip: thetopskip (numbertopskip sp)

    70% topskip: thedimexpr 7topskip/10relax (numberdimexpr 7topskip/10relax sp)

    setlength{multipletopskip}{0.7topskip}
    0.7 topskip: themultipletopskip (numbermultipletopskip sp)

    setlength{multipletopskip}{0.70001topskip}
    0.70001 topskip: themultipletopskip (numbermultipletopskip sp)

    end{document}


    As you see, 0.7topskip is accurate up to 2sp, less than 0.00009mm.2



    Unless you completely override TeX's computation by using a different model such as IEEE754 (decimal32) as is done in Werner's answer, you can't get “exact” values.





    Footnotes



    1 When TeX was written, there was no agreed upon standard for floating-point computations and Knuth's aim was to obtain the same output on every machine TeX was implemented on. Using 64 bits instead of 32 could have achieved “better” accuracy, but at the expense of speed and need for memory: PC's of that time might have even less than 640 kiB of RAM.



    2 Being a skip, it would be more sensible to use glueexpr rather than dimexpr, as noted by GuM in comments. Note that <factor><skip register> will discard the plus and minus components, whereas multiply and divide don't. So



    setlength{multipletopskip}{glueexprtopskip*7/10relax}


    could be better.






    share|improve this answer





















    • 2





      In fact, how tiny these differences are becomes clearer when we switch to small units: a difference of 10 sp is about 53 nanometres. As The TeXbook says “Since the wavelength of visible light is approximately 100 sp, [DEK adds comment in texbook.tex: in fact, violet=75sp, red=135sp] rounding errors of a few sp make no difference to the eye”.

      – ShreevatsaR
      Feb 7 at 12:49











    • Don't you mean 0.1pt is approx. 0.03mm, not 0.3mm? 0.3mm is about 1/3 of a mm, which is about 1/75 of an inch, which is about 1pt not 0.1pt.

      – alephzero
      Feb 7 at 16:09






    • 1





      This answer contains the implicit remark that eTeX’s dimexpr (or glueexpr) provides better precision: why not to make this remark explicit?

      – GuM
      Feb 7 at 18:59






    • 1





      @user0: I don’t think it is a good idea to allow the topskip glue to stretch or shrink; nonetheless, Knuth decided to make topskip a <glue parameter>, not a <dimen parameter>, so, in the principle, using glueexpr should be safer (and more elegant). It depends, however, on what you are trying to achieve: you may well want to kill tpskip’s shrinkability/stretchability intentionally.

      – GuM
      Feb 7 at 19:15








    • 1





      @user0 7topskip discards the stretch, if you don't want to do that use setlength{myLengthG}{glueexprtopskip*7/10relax}

      – David Carlisle
      Feb 7 at 20:15














    13












    13








    13







    There is no way to get a length of 458752sp from <factor>topskip if topskip has the value 10pt, that is, 655360sp, because TeX don't do floating-point computations, but fixed-point base two arithmetic.1



    The binary representation of 7/10 is 0.10(1100), parentheses denote the period. and the multiplication rules of TeX can only provide either 458750sp or 458760sp, represented respectively as 6.99997pt and 7.00012pt.



    The difference between the upper and lower best representations is 10sp, which is less than 0.000435 millimeters or 0.00016 points.



    Since the usual value of vfuzz is 0.1pt (less than 0.03mm), there should be no concern about getting an “exact” value: you'd need to cumulate more than 680 such errors in order to exceed the vfuzz.



    documentclass{article}

    newlength{multipletopskip}

    begin{document}

    Topskip: thetopskip (numbertopskip sp)

    70% topskip: thedimexpr 7topskip/10relax (numberdimexpr 7topskip/10relax sp)

    setlength{multipletopskip}{0.7topskip}
    0.7 topskip: themultipletopskip (numbermultipletopskip sp)

    setlength{multipletopskip}{0.70001topskip}
    0.70001 topskip: themultipletopskip (numbermultipletopskip sp)

    end{document}


    As you see, 0.7topskip is accurate up to 2sp, less than 0.00009mm.2



    Unless you completely override TeX's computation by using a different model such as IEEE754 (decimal32) as is done in Werner's answer, you can't get “exact” values.





    Footnotes



    1 When TeX was written, there was no agreed upon standard for floating-point computations and Knuth's aim was to obtain the same output on every machine TeX was implemented on. Using 64 bits instead of 32 could have achieved “better” accuracy, but at the expense of speed and need for memory: PC's of that time might have even less than 640 kiB of RAM.



    2 Being a skip, it would be more sensible to use glueexpr rather than dimexpr, as noted by GuM in comments. Note that <factor><skip register> will discard the plus and minus components, whereas multiply and divide don't. So



    setlength{multipletopskip}{glueexprtopskip*7/10relax}


    could be better.






    share|improve this answer















    There is no way to get a length of 458752sp from <factor>topskip if topskip has the value 10pt, that is, 655360sp, because TeX don't do floating-point computations, but fixed-point base two arithmetic.1



    The binary representation of 7/10 is 0.10(1100), parentheses denote the period. and the multiplication rules of TeX can only provide either 458750sp or 458760sp, represented respectively as 6.99997pt and 7.00012pt.



    The difference between the upper and lower best representations is 10sp, which is less than 0.000435 millimeters or 0.00016 points.



    Since the usual value of vfuzz is 0.1pt (less than 0.03mm), there should be no concern about getting an “exact” value: you'd need to cumulate more than 680 such errors in order to exceed the vfuzz.



    documentclass{article}

    newlength{multipletopskip}

    begin{document}

    Topskip: thetopskip (numbertopskip sp)

    70% topskip: thedimexpr 7topskip/10relax (numberdimexpr 7topskip/10relax sp)

    setlength{multipletopskip}{0.7topskip}
    0.7 topskip: themultipletopskip (numbermultipletopskip sp)

    setlength{multipletopskip}{0.70001topskip}
    0.70001 topskip: themultipletopskip (numbermultipletopskip sp)

    end{document}


    As you see, 0.7topskip is accurate up to 2sp, less than 0.00009mm.2



    Unless you completely override TeX's computation by using a different model such as IEEE754 (decimal32) as is done in Werner's answer, you can't get “exact” values.





    Footnotes



    1 When TeX was written, there was no agreed upon standard for floating-point computations and Knuth's aim was to obtain the same output on every machine TeX was implemented on. Using 64 bits instead of 32 could have achieved “better” accuracy, but at the expense of speed and need for memory: PC's of that time might have even less than 640 kiB of RAM.



    2 Being a skip, it would be more sensible to use glueexpr rather than dimexpr, as noted by GuM in comments. Note that <factor><skip register> will discard the plus and minus components, whereas multiply and divide don't. So



    setlength{multipletopskip}{glueexprtopskip*7/10relax}


    could be better.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Feb 7 at 21:14

























    answered Feb 7 at 11:33









    egregegreg

    730k8819283242




    730k8819283242








    • 2





      In fact, how tiny these differences are becomes clearer when we switch to small units: a difference of 10 sp is about 53 nanometres. As The TeXbook says “Since the wavelength of visible light is approximately 100 sp, [DEK adds comment in texbook.tex: in fact, violet=75sp, red=135sp] rounding errors of a few sp make no difference to the eye”.

      – ShreevatsaR
      Feb 7 at 12:49











    • Don't you mean 0.1pt is approx. 0.03mm, not 0.3mm? 0.3mm is about 1/3 of a mm, which is about 1/75 of an inch, which is about 1pt not 0.1pt.

      – alephzero
      Feb 7 at 16:09






    • 1





      This answer contains the implicit remark that eTeX’s dimexpr (or glueexpr) provides better precision: why not to make this remark explicit?

      – GuM
      Feb 7 at 18:59






    • 1





      @user0: I don’t think it is a good idea to allow the topskip glue to stretch or shrink; nonetheless, Knuth decided to make topskip a <glue parameter>, not a <dimen parameter>, so, in the principle, using glueexpr should be safer (and more elegant). It depends, however, on what you are trying to achieve: you may well want to kill tpskip’s shrinkability/stretchability intentionally.

      – GuM
      Feb 7 at 19:15








    • 1





      @user0 7topskip discards the stretch, if you don't want to do that use setlength{myLengthG}{glueexprtopskip*7/10relax}

      – David Carlisle
      Feb 7 at 20:15














    • 2





      In fact, how tiny these differences are becomes clearer when we switch to small units: a difference of 10 sp is about 53 nanometres. As The TeXbook says “Since the wavelength of visible light is approximately 100 sp, [DEK adds comment in texbook.tex: in fact, violet=75sp, red=135sp] rounding errors of a few sp make no difference to the eye”.

      – ShreevatsaR
      Feb 7 at 12:49











    • Don't you mean 0.1pt is approx. 0.03mm, not 0.3mm? 0.3mm is about 1/3 of a mm, which is about 1/75 of an inch, which is about 1pt not 0.1pt.

      – alephzero
      Feb 7 at 16:09






    • 1





      This answer contains the implicit remark that eTeX’s dimexpr (or glueexpr) provides better precision: why not to make this remark explicit?

      – GuM
      Feb 7 at 18:59






    • 1





      @user0: I don’t think it is a good idea to allow the topskip glue to stretch or shrink; nonetheless, Knuth decided to make topskip a <glue parameter>, not a <dimen parameter>, so, in the principle, using glueexpr should be safer (and more elegant). It depends, however, on what you are trying to achieve: you may well want to kill tpskip’s shrinkability/stretchability intentionally.

      – GuM
      Feb 7 at 19:15








    • 1





      @user0 7topskip discards the stretch, if you don't want to do that use setlength{myLengthG}{glueexprtopskip*7/10relax}

      – David Carlisle
      Feb 7 at 20:15








    2




    2





    In fact, how tiny these differences are becomes clearer when we switch to small units: a difference of 10 sp is about 53 nanometres. As The TeXbook says “Since the wavelength of visible light is approximately 100 sp, [DEK adds comment in texbook.tex: in fact, violet=75sp, red=135sp] rounding errors of a few sp make no difference to the eye”.

    – ShreevatsaR
    Feb 7 at 12:49





    In fact, how tiny these differences are becomes clearer when we switch to small units: a difference of 10 sp is about 53 nanometres. As The TeXbook says “Since the wavelength of visible light is approximately 100 sp, [DEK adds comment in texbook.tex: in fact, violet=75sp, red=135sp] rounding errors of a few sp make no difference to the eye”.

    – ShreevatsaR
    Feb 7 at 12:49













    Don't you mean 0.1pt is approx. 0.03mm, not 0.3mm? 0.3mm is about 1/3 of a mm, which is about 1/75 of an inch, which is about 1pt not 0.1pt.

    – alephzero
    Feb 7 at 16:09





    Don't you mean 0.1pt is approx. 0.03mm, not 0.3mm? 0.3mm is about 1/3 of a mm, which is about 1/75 of an inch, which is about 1pt not 0.1pt.

    – alephzero
    Feb 7 at 16:09




    1




    1





    This answer contains the implicit remark that eTeX’s dimexpr (or glueexpr) provides better precision: why not to make this remark explicit?

    – GuM
    Feb 7 at 18:59





    This answer contains the implicit remark that eTeX’s dimexpr (or glueexpr) provides better precision: why not to make this remark explicit?

    – GuM
    Feb 7 at 18:59




    1




    1





    @user0: I don’t think it is a good idea to allow the topskip glue to stretch or shrink; nonetheless, Knuth decided to make topskip a <glue parameter>, not a <dimen parameter>, so, in the principle, using glueexpr should be safer (and more elegant). It depends, however, on what you are trying to achieve: you may well want to kill tpskip’s shrinkability/stretchability intentionally.

    – GuM
    Feb 7 at 19:15







    @user0: I don’t think it is a good idea to allow the topskip glue to stretch or shrink; nonetheless, Knuth decided to make topskip a <glue parameter>, not a <dimen parameter>, so, in the principle, using glueexpr should be safer (and more elegant). It depends, however, on what you are trying to achieve: you may well want to kill tpskip’s shrinkability/stretchability intentionally.

    – GuM
    Feb 7 at 19:15






    1




    1





    @user0 7topskip discards the stretch, if you don't want to do that use setlength{myLengthG}{glueexprtopskip*7/10relax}

    – David Carlisle
    Feb 7 at 20:15





    @user0 7topskip discards the stretch, if you don't want to do that use setlength{myLengthG}{glueexprtopskip*7/10relax}

    – David Carlisle
    Feb 7 at 20:15











    2














    This should not be an answer, but rather a comment both to @egreg’s answer and to David Carlisle’s; unfortunately, I need to include some sample code, and this can only be done (in an intelligible form) in an answer. I willingly concede that it doesn’t add anything substantial to those two answers—except, perhaps, a bit of clarity. I’m ready to remove this answer if either of the abovementioned authors clarifies his.



    As already repeatedly remarked, Knuth’s TeX does (or rather, did) its calculations with dimensions using 32-bit fixed points arithmetics; all modern typesetting engines, however, incorporate the so-called “e-TeX” (for Extended, or Enhanced, TeX) extensions, among which is the ability to perform dimension scaling, that is, multiplication of a dimension for a fraction, with 64-bit precision. More precisely, e-TeX extensions introduce a new type of syntax by means of which dimensions can be specified, that enables the use of “expressions”, in the customary sense of the term; in particular, you are allowed to multiply a certain dimension for a fraction, as in



    setlengthsomeotherdimen{dimexpr somedimen * 7/10}


    (the primitive dimexpr marks the beginning of a “dimen-valued” expression; the end is implicitly marked by the first token that cannot be interpreted as part of the expression itself—you can assume it is the closing brace, in the above example). When this is done, a 64-bit temporary register is used to hold the intermediate result of the multiplication of the dimension for the numerator of the fraction (somedimen * 7, in the above example); thank to this expedient, when the subsequent division for the denominator (10, in our case) is performed, all bits of the final (32-bit) result are significant.



    As already said, dimexpr starts a “dimen-valued” expression; there exists a similar primitive for “glue-valued” expressions, named glueexpr. Note, however, the difference, that others have already explained, between



    setlengthsomeotherskip{glueexpr 7someskip /10}


    and



    setlengthsomeotherskip{glueexpr someskip * 7/10}


    In the former, 7someskip is converted to a dimen value, destroying (that is, zeroing) its stretch and shrink components, if any; this doesn’t happen with the latter.



    The following code proves that



    setlength{someotherskip}{glueexpr topskip * 7/10}


    attains the same precision as explicitly setting someotherskip to 7pt (and similarly for the stretch and shrink components, if present):



    % My standard header for TeX.SX answers:
    documentclass[a4paper]{article} % To avoid confusion, let us explicitly
    % declare the paper format.

    usepackage[T1]{fontenc} % Not always necessary, but recommended.
    % End of standard header. What follows pertains to the problem at hand.

    newcommand*{ReportDimen}[2]{%
    #1:>texttt{the #2}\>texttt{(number #2sp)}\%
    }
    newcommand*{ReportGlue}[2]{%
    #1:>texttt{the #2}\>%
    texttt{(%
    number #2sp
    plus numberexpandafterdimexprthegluestretch #2relax sp
    minus numberexpandafterdimexprtheglueshrink #2relax sp%
    )}\%
    }

    setlength{topskip}{10.0pt plus 1pt minus 1 pt}
    newlength{smallertopskip}
    setlength{smallertopskip}{.700004577636718749999999999999999999999999999999topskip}
    newlength{largertopskip}
    setlength{largertopskip}{.700004577636718750000000000000000000000000000000topskip}
    newlength{eTeXTopskip}
    setlength{eTeXTopskip}{glueexpr topskip * 7/10}
    newlength{sevenpoints}
    setlength{sevenpoints}{7.0pt plus .7pt minus .7pt}



    begin{document}

    begin{tabbing}
    Topskip:quad=kill
    ReportGlue {Topskip}{topskip}
    ReportDimen{Smaller}{smallertopskip}
    ReportDimen{Larger}{largertopskip}
    ReportGlue {eTeX's}{eTeXTopskip}
    ReportGlue {Exact}{sevenpoints}
    end{tabbing}

    end{document}


    (values in scaled points are shown as well).






    share|improve this answer






























      2














      This should not be an answer, but rather a comment both to @egreg’s answer and to David Carlisle’s; unfortunately, I need to include some sample code, and this can only be done (in an intelligible form) in an answer. I willingly concede that it doesn’t add anything substantial to those two answers—except, perhaps, a bit of clarity. I’m ready to remove this answer if either of the abovementioned authors clarifies his.



      As already repeatedly remarked, Knuth’s TeX does (or rather, did) its calculations with dimensions using 32-bit fixed points arithmetics; all modern typesetting engines, however, incorporate the so-called “e-TeX” (for Extended, or Enhanced, TeX) extensions, among which is the ability to perform dimension scaling, that is, multiplication of a dimension for a fraction, with 64-bit precision. More precisely, e-TeX extensions introduce a new type of syntax by means of which dimensions can be specified, that enables the use of “expressions”, in the customary sense of the term; in particular, you are allowed to multiply a certain dimension for a fraction, as in



      setlengthsomeotherdimen{dimexpr somedimen * 7/10}


      (the primitive dimexpr marks the beginning of a “dimen-valued” expression; the end is implicitly marked by the first token that cannot be interpreted as part of the expression itself—you can assume it is the closing brace, in the above example). When this is done, a 64-bit temporary register is used to hold the intermediate result of the multiplication of the dimension for the numerator of the fraction (somedimen * 7, in the above example); thank to this expedient, when the subsequent division for the denominator (10, in our case) is performed, all bits of the final (32-bit) result are significant.



      As already said, dimexpr starts a “dimen-valued” expression; there exists a similar primitive for “glue-valued” expressions, named glueexpr. Note, however, the difference, that others have already explained, between



      setlengthsomeotherskip{glueexpr 7someskip /10}


      and



      setlengthsomeotherskip{glueexpr someskip * 7/10}


      In the former, 7someskip is converted to a dimen value, destroying (that is, zeroing) its stretch and shrink components, if any; this doesn’t happen with the latter.



      The following code proves that



      setlength{someotherskip}{glueexpr topskip * 7/10}


      attains the same precision as explicitly setting someotherskip to 7pt (and similarly for the stretch and shrink components, if present):



      % My standard header for TeX.SX answers:
      documentclass[a4paper]{article} % To avoid confusion, let us explicitly
      % declare the paper format.

      usepackage[T1]{fontenc} % Not always necessary, but recommended.
      % End of standard header. What follows pertains to the problem at hand.

      newcommand*{ReportDimen}[2]{%
      #1:>texttt{the #2}\>texttt{(number #2sp)}\%
      }
      newcommand*{ReportGlue}[2]{%
      #1:>texttt{the #2}\>%
      texttt{(%
      number #2sp
      plus numberexpandafterdimexprthegluestretch #2relax sp
      minus numberexpandafterdimexprtheglueshrink #2relax sp%
      )}\%
      }

      setlength{topskip}{10.0pt plus 1pt minus 1 pt}
      newlength{smallertopskip}
      setlength{smallertopskip}{.700004577636718749999999999999999999999999999999topskip}
      newlength{largertopskip}
      setlength{largertopskip}{.700004577636718750000000000000000000000000000000topskip}
      newlength{eTeXTopskip}
      setlength{eTeXTopskip}{glueexpr topskip * 7/10}
      newlength{sevenpoints}
      setlength{sevenpoints}{7.0pt plus .7pt minus .7pt}



      begin{document}

      begin{tabbing}
      Topskip:quad=kill
      ReportGlue {Topskip}{topskip}
      ReportDimen{Smaller}{smallertopskip}
      ReportDimen{Larger}{largertopskip}
      ReportGlue {eTeX's}{eTeXTopskip}
      ReportGlue {Exact}{sevenpoints}
      end{tabbing}

      end{document}


      (values in scaled points are shown as well).






      share|improve this answer




























        2












        2








        2







        This should not be an answer, but rather a comment both to @egreg’s answer and to David Carlisle’s; unfortunately, I need to include some sample code, and this can only be done (in an intelligible form) in an answer. I willingly concede that it doesn’t add anything substantial to those two answers—except, perhaps, a bit of clarity. I’m ready to remove this answer if either of the abovementioned authors clarifies his.



        As already repeatedly remarked, Knuth’s TeX does (or rather, did) its calculations with dimensions using 32-bit fixed points arithmetics; all modern typesetting engines, however, incorporate the so-called “e-TeX” (for Extended, or Enhanced, TeX) extensions, among which is the ability to perform dimension scaling, that is, multiplication of a dimension for a fraction, with 64-bit precision. More precisely, e-TeX extensions introduce a new type of syntax by means of which dimensions can be specified, that enables the use of “expressions”, in the customary sense of the term; in particular, you are allowed to multiply a certain dimension for a fraction, as in



        setlengthsomeotherdimen{dimexpr somedimen * 7/10}


        (the primitive dimexpr marks the beginning of a “dimen-valued” expression; the end is implicitly marked by the first token that cannot be interpreted as part of the expression itself—you can assume it is the closing brace, in the above example). When this is done, a 64-bit temporary register is used to hold the intermediate result of the multiplication of the dimension for the numerator of the fraction (somedimen * 7, in the above example); thank to this expedient, when the subsequent division for the denominator (10, in our case) is performed, all bits of the final (32-bit) result are significant.



        As already said, dimexpr starts a “dimen-valued” expression; there exists a similar primitive for “glue-valued” expressions, named glueexpr. Note, however, the difference, that others have already explained, between



        setlengthsomeotherskip{glueexpr 7someskip /10}


        and



        setlengthsomeotherskip{glueexpr someskip * 7/10}


        In the former, 7someskip is converted to a dimen value, destroying (that is, zeroing) its stretch and shrink components, if any; this doesn’t happen with the latter.



        The following code proves that



        setlength{someotherskip}{glueexpr topskip * 7/10}


        attains the same precision as explicitly setting someotherskip to 7pt (and similarly for the stretch and shrink components, if present):



        % My standard header for TeX.SX answers:
        documentclass[a4paper]{article} % To avoid confusion, let us explicitly
        % declare the paper format.

        usepackage[T1]{fontenc} % Not always necessary, but recommended.
        % End of standard header. What follows pertains to the problem at hand.

        newcommand*{ReportDimen}[2]{%
        #1:>texttt{the #2}\>texttt{(number #2sp)}\%
        }
        newcommand*{ReportGlue}[2]{%
        #1:>texttt{the #2}\>%
        texttt{(%
        number #2sp
        plus numberexpandafterdimexprthegluestretch #2relax sp
        minus numberexpandafterdimexprtheglueshrink #2relax sp%
        )}\%
        }

        setlength{topskip}{10.0pt plus 1pt minus 1 pt}
        newlength{smallertopskip}
        setlength{smallertopskip}{.700004577636718749999999999999999999999999999999topskip}
        newlength{largertopskip}
        setlength{largertopskip}{.700004577636718750000000000000000000000000000000topskip}
        newlength{eTeXTopskip}
        setlength{eTeXTopskip}{glueexpr topskip * 7/10}
        newlength{sevenpoints}
        setlength{sevenpoints}{7.0pt plus .7pt minus .7pt}



        begin{document}

        begin{tabbing}
        Topskip:quad=kill
        ReportGlue {Topskip}{topskip}
        ReportDimen{Smaller}{smallertopskip}
        ReportDimen{Larger}{largertopskip}
        ReportGlue {eTeX's}{eTeXTopskip}
        ReportGlue {Exact}{sevenpoints}
        end{tabbing}

        end{document}


        (values in scaled points are shown as well).






        share|improve this answer















        This should not be an answer, but rather a comment both to @egreg’s answer and to David Carlisle’s; unfortunately, I need to include some sample code, and this can only be done (in an intelligible form) in an answer. I willingly concede that it doesn’t add anything substantial to those two answers—except, perhaps, a bit of clarity. I’m ready to remove this answer if either of the abovementioned authors clarifies his.



        As already repeatedly remarked, Knuth’s TeX does (or rather, did) its calculations with dimensions using 32-bit fixed points arithmetics; all modern typesetting engines, however, incorporate the so-called “e-TeX” (for Extended, or Enhanced, TeX) extensions, among which is the ability to perform dimension scaling, that is, multiplication of a dimension for a fraction, with 64-bit precision. More precisely, e-TeX extensions introduce a new type of syntax by means of which dimensions can be specified, that enables the use of “expressions”, in the customary sense of the term; in particular, you are allowed to multiply a certain dimension for a fraction, as in



        setlengthsomeotherdimen{dimexpr somedimen * 7/10}


        (the primitive dimexpr marks the beginning of a “dimen-valued” expression; the end is implicitly marked by the first token that cannot be interpreted as part of the expression itself—you can assume it is the closing brace, in the above example). When this is done, a 64-bit temporary register is used to hold the intermediate result of the multiplication of the dimension for the numerator of the fraction (somedimen * 7, in the above example); thank to this expedient, when the subsequent division for the denominator (10, in our case) is performed, all bits of the final (32-bit) result are significant.



        As already said, dimexpr starts a “dimen-valued” expression; there exists a similar primitive for “glue-valued” expressions, named glueexpr. Note, however, the difference, that others have already explained, between



        setlengthsomeotherskip{glueexpr 7someskip /10}


        and



        setlengthsomeotherskip{glueexpr someskip * 7/10}


        In the former, 7someskip is converted to a dimen value, destroying (that is, zeroing) its stretch and shrink components, if any; this doesn’t happen with the latter.



        The following code proves that



        setlength{someotherskip}{glueexpr topskip * 7/10}


        attains the same precision as explicitly setting someotherskip to 7pt (and similarly for the stretch and shrink components, if present):



        % My standard header for TeX.SX answers:
        documentclass[a4paper]{article} % To avoid confusion, let us explicitly
        % declare the paper format.

        usepackage[T1]{fontenc} % Not always necessary, but recommended.
        % End of standard header. What follows pertains to the problem at hand.

        newcommand*{ReportDimen}[2]{%
        #1:>texttt{the #2}\>texttt{(number #2sp)}\%
        }
        newcommand*{ReportGlue}[2]{%
        #1:>texttt{the #2}\>%
        texttt{(%
        number #2sp
        plus numberexpandafterdimexprthegluestretch #2relax sp
        minus numberexpandafterdimexprtheglueshrink #2relax sp%
        )}\%
        }

        setlength{topskip}{10.0pt plus 1pt minus 1 pt}
        newlength{smallertopskip}
        setlength{smallertopskip}{.700004577636718749999999999999999999999999999999topskip}
        newlength{largertopskip}
        setlength{largertopskip}{.700004577636718750000000000000000000000000000000topskip}
        newlength{eTeXTopskip}
        setlength{eTeXTopskip}{glueexpr topskip * 7/10}
        newlength{sevenpoints}
        setlength{sevenpoints}{7.0pt plus .7pt minus .7pt}



        begin{document}

        begin{tabbing}
        Topskip:quad=kill
        ReportGlue {Topskip}{topskip}
        ReportDimen{Smaller}{smallertopskip}
        ReportDimen{Larger}{largertopskip}
        ReportGlue {eTeX's}{eTeXTopskip}
        ReportGlue {Exact}{sevenpoints}
        end{tabbing}

        end{document}


        (values in scaled points are shown as well).







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Feb 8 at 17:49

























        answered Feb 7 at 23:34









        GuMGuM

        16.7k2459




        16.7k2459






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to TeX - LaTeX Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f473706%2f7-0pt-%25e2%2589%25a0-x%25e2%258b%258510-0pt-for-all-x%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Human spaceflight

            Can not write log (Is /dev/pts mounted?) - openpty in Ubuntu-on-Windows?

            張江高科駅