7.0pt ≠ x⋅10.0pt for all x

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












15















Consider the following input:



documentclassarticle
begindocument
newlengthsmallertopskip
setlengthsmallertopskip.700004577636718749999999999999999999999999999999topskip
newlengthlargertopskip
setlengthlargertopskip.700004577636718750000000000000000000000000000000topskip

Topskip: thetopskip

Smaller: thesmallertopskip

Larger: thelargertopskip
enddocument


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



newlengthmyLength
setlengthmyLengthmultxtopskip
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.

    – user0
    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.

    – user0
    Feb 7 at 18:49
















15















Consider the following input:



documentclassarticle
begindocument
newlengthsmallertopskip
setlengthsmallertopskip.700004577636718749999999999999999999999999999999topskip
newlengthlargertopskip
setlengthlargertopskip.700004577636718750000000000000000000000000000000topskip

Topskip: thetopskip

Smaller: thesmallertopskip

Larger: thelargertopskip
enddocument


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



newlengthmyLength
setlengthmyLengthmultxtopskip
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.

    – user0
    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.

    – user0
    Feb 7 at 18:49














15












15








15


2






Consider the following input:



documentclassarticle
begindocument
newlengthsmallertopskip
setlengthsmallertopskip.700004577636718749999999999999999999999999999999topskip
newlengthlargertopskip
setlengthlargertopskip.700004577636718750000000000000000000000000000000topskip

Topskip: thetopskip

Smaller: thesmallertopskip

Larger: thelargertopskip
enddocument


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



newlengthmyLength
setlengthmyLengthmultxtopskip
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:



documentclassarticle
begindocument
newlengthsmallertopskip
setlengthsmallertopskip.700004577636718749999999999999999999999999999999topskip
newlengthlargertopskip
setlengthlargertopskip.700004577636718750000000000000000000000000000000topskip

Topskip: thetopskip

Smaller: thesmallertopskip

Larger: thelargertopskip
enddocument


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



newlengthmyLength
setlengthmyLengthmultxtopskip
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







user0

















asked Feb 7 at 3:46









user0user0

584121




584121







  • 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.

    – user0
    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.

    – user0
    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.

    – user0
    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.

    – user0
    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.

– user0
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.

– user0
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.

– user0
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.

– user0
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.



documentclassarticle

begindocument
newlengthsmallertopskip
setlengthsmallertopskipdimexpr 7topskip/10relax

Topskip: thetopskip

Smaller: thesmallertopskip


enddocument


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.

    – user0
    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




documentclassarticle

usepackagexfp

begindocument

newlengthmyLength%
setlengthmyLengthfpevalround(0.7 * topskip, 0)pt%
themyLength

enddocument


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



newcommandmult[2]fpevalround(#1 * #2, 0)pt


to support your input



setlengthmyLengthmult0.7topskip





share|improve this answer























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

    – user0
    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 setlengthmylenth7pt.

    – Ulrike Fischer
    Feb 7 at 7:50






  • 2





    @user0 that was a joke. But I would use setlengthmyLengthfpevaldim_to_decimal:n topskip * 0.7pt 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.



documentclassarticle

newlengthmultipletopskip

begindocument

Topskip: thetopskip (numbertopskip sp)

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

setlengthmultipletopskip0.7topskip
0.7 topskip: themultipletopskip (numbermultipletopskip sp)

setlengthmultipletopskip0.70001topskip
0.70001 topskip: themultipletopskip (numbermultipletopskip sp)

enddocument


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



setlengthmultipletopskipglueexprtopskip*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 setlengthmyLengthGglueexprtopskip*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



setlengthsomeotherdimendimexpr 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



setlengthsomeotherskipglueexpr 7someskip /10


and



setlengthsomeotherskipglueexpr 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



setlengthsomeotherskipglueexpr 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:>textttthe #2\>texttt(number #2sp)\%

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


setlengthtopskip10.0pt plus 1pt minus 1 pt
newlengthsmallertopskip
setlengthsmallertopskip.700004577636718749999999999999999999999999999999topskip
newlengthlargertopskip
setlengthlargertopskip.700004577636718750000000000000000000000000000000topskip
newlengtheTeXTopskip
setlengtheTeXTopskipglueexpr topskip * 7/10
newlengthsevenpoints
setlengthsevenpoints7.0pt plus .7pt minus .7pt



begindocument

begintabbing
Topskip:quad=kill
ReportGlue Topskiptopskip
ReportDimenSmallersmallertopskip
ReportDimenLargerlargertopskip
ReportGlue eTeX'seTeXTopskip
ReportGlue Exactsevenpoints
endtabbing

enddocument


(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.



    documentclassarticle

    begindocument
    newlengthsmallertopskip
    setlengthsmallertopskipdimexpr 7topskip/10relax

    Topskip: thetopskip

    Smaller: thesmallertopskip


    enddocument


    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.

      – user0
      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.



    documentclassarticle

    begindocument
    newlengthsmallertopskip
    setlengthsmallertopskipdimexpr 7topskip/10relax

    Topskip: thetopskip

    Smaller: thesmallertopskip


    enddocument


    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.

      – user0
      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.



    documentclassarticle

    begindocument
    newlengthsmallertopskip
    setlengthsmallertopskipdimexpr 7topskip/10relax

    Topskip: thetopskip

    Smaller: thesmallertopskip


    enddocument


    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.



    documentclassarticle

    begindocument
    newlengthsmallertopskip
    setlengthsmallertopskipdimexpr 7topskip/10relax

    Topskip: thetopskip

    Smaller: thesmallertopskip


    enddocument


    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

    492k4111371885




    492k4111371885












    • 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.

      – user0
      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.

      – user0
      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.

    – user0
    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.

    – user0
    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




    documentclassarticle

    usepackagexfp

    begindocument

    newlengthmyLength%
    setlengthmyLengthfpevalround(0.7 * topskip, 0)pt%
    themyLength

    enddocument


    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



    newcommandmult[2]fpevalround(#1 * #2, 0)pt


    to support your input



    setlengthmyLengthmult0.7topskip





    share|improve this answer























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

      – user0
      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 setlengthmylenth7pt.

      – Ulrike Fischer
      Feb 7 at 7:50






    • 2





      @user0 that was a joke. But I would use setlengthmyLengthfpevaldim_to_decimal:n topskip * 0.7pt instead of rounding the result.

      – Ulrike Fischer
      Feb 7 at 19:12















    18














    Use xfp:




    7.0pt




    documentclassarticle

    usepackagexfp

    begindocument

    newlengthmyLength%
    setlengthmyLengthfpevalround(0.7 * topskip, 0)pt%
    themyLength

    enddocument


    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



    newcommandmult[2]fpevalround(#1 * #2, 0)pt


    to support your input



    setlengthmyLengthmult0.7topskip





    share|improve this answer























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

      – user0
      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 setlengthmylenth7pt.

      – Ulrike Fischer
      Feb 7 at 7:50






    • 2





      @user0 that was a joke. But I would use setlengthmyLengthfpevaldim_to_decimal:n topskip * 0.7pt instead of rounding the result.

      – Ulrike Fischer
      Feb 7 at 19:12













    18












    18








    18







    Use xfp:




    7.0pt




    documentclassarticle

    usepackagexfp

    begindocument

    newlengthmyLength%
    setlengthmyLengthfpevalround(0.7 * topskip, 0)pt%
    themyLength

    enddocument


    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



    newcommandmult[2]fpevalround(#1 * #2, 0)pt


    to support your input



    setlengthmyLengthmult0.7topskip





    share|improve this answer













    Use xfp:




    7.0pt




    documentclassarticle

    usepackagexfp

    begindocument

    newlengthmyLength%
    setlengthmyLengthfpevalround(0.7 * topskip, 0)pt%
    themyLength

    enddocument


    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



    newcommandmult[2]fpevalround(#1 * #2, 0)pt


    to support your input



    setlengthmyLengthmult0.7topskip






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Feb 7 at 3:54









    WernerWerner

    446k699841690




    446k699841690












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

      – user0
      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 setlengthmylenth7pt.

      – Ulrike Fischer
      Feb 7 at 7:50






    • 2





      @user0 that was a joke. But I would use setlengthmyLengthfpevaldim_to_decimal:n topskip * 0.7pt 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?

      – user0
      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 setlengthmylenth7pt.

      – Ulrike Fischer
      Feb 7 at 7:50






    • 2





      @user0 that was a joke. But I would use setlengthmyLengthfpevaldim_to_decimal:n topskip * 0.7pt 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?

    – user0
    Feb 7 at 5:14






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

    – user0
    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 setlengthmylenth7pt.

    – Ulrike Fischer
    Feb 7 at 7:50





    This looks like a quite complicated way to say setlengthmylenth7pt.

    – Ulrike Fischer
    Feb 7 at 7:50




    2




    2





    @user0 that was a joke. But I would use setlengthmyLengthfpevaldim_to_decimal:n topskip * 0.7pt instead of rounding the result.

    – Ulrike Fischer
    Feb 7 at 19:12





    @user0 that was a joke. But I would use setlengthmyLengthfpevaldim_to_decimal:n topskip * 0.7pt 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.



    documentclassarticle

    newlengthmultipletopskip

    begindocument

    Topskip: thetopskip (numbertopskip sp)

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

    setlengthmultipletopskip0.7topskip
    0.7 topskip: themultipletopskip (numbermultipletopskip sp)

    setlengthmultipletopskip0.70001topskip
    0.70001 topskip: themultipletopskip (numbermultipletopskip sp)

    enddocument


    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



    setlengthmultipletopskipglueexprtopskip*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 setlengthmyLengthGglueexprtopskip*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.



    documentclassarticle

    newlengthmultipletopskip

    begindocument

    Topskip: thetopskip (numbertopskip sp)

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

    setlengthmultipletopskip0.7topskip
    0.7 topskip: themultipletopskip (numbermultipletopskip sp)

    setlengthmultipletopskip0.70001topskip
    0.70001 topskip: themultipletopskip (numbermultipletopskip sp)

    enddocument


    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



    setlengthmultipletopskipglueexprtopskip*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 setlengthmyLengthGglueexprtopskip*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.



    documentclassarticle

    newlengthmultipletopskip

    begindocument

    Topskip: thetopskip (numbertopskip sp)

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

    setlengthmultipletopskip0.7topskip
    0.7 topskip: themultipletopskip (numbermultipletopskip sp)

    setlengthmultipletopskip0.70001topskip
    0.70001 topskip: themultipletopskip (numbermultipletopskip sp)

    enddocument


    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



    setlengthmultipletopskipglueexprtopskip*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.



    documentclassarticle

    newlengthmultipletopskip

    begindocument

    Topskip: thetopskip (numbertopskip sp)

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

    setlengthmultipletopskip0.7topskip
    0.7 topskip: themultipletopskip (numbermultipletopskip sp)

    setlengthmultipletopskip0.70001topskip
    0.70001 topskip: themultipletopskip (numbermultipletopskip sp)

    enddocument


    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



    setlengthmultipletopskipglueexprtopskip*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

    723k8819173220




    723k8819173220







    • 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 setlengthmyLengthGglueexprtopskip*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 setlengthmyLengthGglueexprtopskip*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 setlengthmyLengthGglueexprtopskip*7/10relax

    – David Carlisle
    Feb 7 at 20:15





    @user0 7topskip discards the stretch, if you don't want to do that use setlengthmyLengthGglueexprtopskip*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



    setlengthsomeotherdimendimexpr 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



    setlengthsomeotherskipglueexpr 7someskip /10


    and



    setlengthsomeotherskipglueexpr 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



    setlengthsomeotherskipglueexpr 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:>textttthe #2\>texttt(number #2sp)\%

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


    setlengthtopskip10.0pt plus 1pt minus 1 pt
    newlengthsmallertopskip
    setlengthsmallertopskip.700004577636718749999999999999999999999999999999topskip
    newlengthlargertopskip
    setlengthlargertopskip.700004577636718750000000000000000000000000000000topskip
    newlengtheTeXTopskip
    setlengtheTeXTopskipglueexpr topskip * 7/10
    newlengthsevenpoints
    setlengthsevenpoints7.0pt plus .7pt minus .7pt



    begindocument

    begintabbing
    Topskip:quad=kill
    ReportGlue Topskiptopskip
    ReportDimenSmallersmallertopskip
    ReportDimenLargerlargertopskip
    ReportGlue eTeX'seTeXTopskip
    ReportGlue Exactsevenpoints
    endtabbing

    enddocument


    (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



      setlengthsomeotherdimendimexpr 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



      setlengthsomeotherskipglueexpr 7someskip /10


      and



      setlengthsomeotherskipglueexpr 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



      setlengthsomeotherskipglueexpr 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:>textttthe #2\>texttt(number #2sp)\%

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


      setlengthtopskip10.0pt plus 1pt minus 1 pt
      newlengthsmallertopskip
      setlengthsmallertopskip.700004577636718749999999999999999999999999999999topskip
      newlengthlargertopskip
      setlengthlargertopskip.700004577636718750000000000000000000000000000000topskip
      newlengtheTeXTopskip
      setlengtheTeXTopskipglueexpr topskip * 7/10
      newlengthsevenpoints
      setlengthsevenpoints7.0pt plus .7pt minus .7pt



      begindocument

      begintabbing
      Topskip:quad=kill
      ReportGlue Topskiptopskip
      ReportDimenSmallersmallertopskip
      ReportDimenLargerlargertopskip
      ReportGlue eTeX'seTeXTopskip
      ReportGlue Exactsevenpoints
      endtabbing

      enddocument


      (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



        setlengthsomeotherdimendimexpr 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



        setlengthsomeotherskipglueexpr 7someskip /10


        and



        setlengthsomeotherskipglueexpr 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



        setlengthsomeotherskipglueexpr 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:>textttthe #2\>texttt(number #2sp)\%

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


        setlengthtopskip10.0pt plus 1pt minus 1 pt
        newlengthsmallertopskip
        setlengthsmallertopskip.700004577636718749999999999999999999999999999999topskip
        newlengthlargertopskip
        setlengthlargertopskip.700004577636718750000000000000000000000000000000topskip
        newlengtheTeXTopskip
        setlengtheTeXTopskipglueexpr topskip * 7/10
        newlengthsevenpoints
        setlengthsevenpoints7.0pt plus .7pt minus .7pt



        begindocument

        begintabbing
        Topskip:quad=kill
        ReportGlue Topskiptopskip
        ReportDimenSmallersmallertopskip
        ReportDimenLargerlargertopskip
        ReportGlue eTeX'seTeXTopskip
        ReportGlue Exactsevenpoints
        endtabbing

        enddocument


        (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



        setlengthsomeotherdimendimexpr 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



        setlengthsomeotherskipglueexpr 7someskip /10


        and



        setlengthsomeotherskipglueexpr 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



        setlengthsomeotherskipglueexpr 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:>textttthe #2\>texttt(number #2sp)\%

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


        setlengthtopskip10.0pt plus 1pt minus 1 pt
        newlengthsmallertopskip
        setlengthsmallertopskip.700004577636718749999999999999999999999999999999topskip
        newlengthlargertopskip
        setlengthlargertopskip.700004577636718750000000000000000000000000000000topskip
        newlengtheTeXTopskip
        setlengtheTeXTopskipglueexpr topskip * 7/10
        newlengthsevenpoints
        setlengthsevenpoints7.0pt plus .7pt minus .7pt



        begindocument

        begintabbing
        Topskip:quad=kill
        ReportGlue Topskiptopskip
        ReportDimenSmallersmallertopskip
        ReportDimenLargerlargertopskip
        ReportGlue eTeX'seTeXTopskip
        ReportGlue Exactsevenpoints
        endtabbing

        enddocument


        (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.6k2457




        16.6k2457



























            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

            How to check contact read email or not when send email to Individual?

            Displaying single band from multi-band raster using QGIS

            How many registers does an x86_64 CPU actually have?