Menu

#2266 prefix %c and %b for 1-999

None
closed-accepted
nobody
2021-06-02
2020-05-25
theozh
No

Shouldn't the prefix for 1-999 be an empty string '' instead of ' ' (space)?

How could I achieve one single space between number and unit for all prefixes?
Following example:

print gprintf('%.1s %cB',123)
print gprintf('%.1s %cB',123456)

# or alternatively

print gprintf('%.1s%cB',123)
print gprintf('%.1s%cB',123456)

Result:

123.0  B
123.5 kB

123.0 B
123.5kB

So, I either get two spaces for numbers 1-100 and one space for the others with prefix,
or I get one space for numbers 1-100 and no space for the others with prefix.

Question: can't the prefix for 1-100 be changed to empty string '' or are there other reasons or restrictions that is has to be like it is?

Discussion

  • theozh

    theozh - 2020-05-25
    • summary: prefix %c and %b for 1-100 --> prefix %c and %b for 1-999
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -1,4 +1,4 @@
    -Shouldn't the prefix for 1-100 be an empty string '' instead of ' ' (space)?
    +Shouldn't the prefix for 1-999 be an empty string '' instead of ' ' (space)?
    
     How could I achieve _one single_ space between number and unit for all prefixes?
     Following example:
    
    • Group: -->
    • Priority: -->
     
  • theozh

    theozh - 2021-01-24

    Since I do not know C, here is a gnuplot attempt to fix this issue. It was triggered by the answer to this StackOverflow question: https://stackoverflow.com/q/65863357/7295599

    I guess this should be easily transferrable to C.

    Code:

    ### gnuplot "fix" for prefix for %c 1-999
    
    prefix(power) = "yzafpnum kMGTPEZY"[(power+24)/3+1 : (power+24)/3 + sgn(abs(power))]
    
    do for [power=-24:24:3] {
        print sprintf("% 3g  '%s'", power, prefix(power))
    }
    ### end of code
    

    Result:

    -24  'y'
    -21  'z'
    -18  'a'
    -15  'f'
    -12  'p'
     -9  'n'
     -6  'u'
     -3  'm'
      0  ''   # zero length
      3  'k'
      6  'M'
      9  'G'
     12  'T'
     15  'P'
     18  'E'
     21  'Z'
     24  'Y'
    
     

    Last edit: theozh 2021-01-24
  • Gabriel Dupras

    Gabriel Dupras - 2021-01-24

    I've tried the patch suggested by maij on stackoverflow here and as far as I can tell it does fix the bug.

    I've attached the patch here for convenience.

     
  • Ethan Merritt

    Ethan Merritt - 2021-01-25

    Is there a standard convention that covers this? It seems to me that the current "extra" space character is there so that in a monospace font the numbers line up consistently and the units also line up consistently. Use of a proportional font messes this up because the various characters are not the same width. Is the output below wrong? right?

    I am inclined to say that the current behaviour with the "extra" space is correct for monospace fonts, and the behaviour with proportional fonts is imperfect both with and without the patch.

    Is the proper fix to have a more complicated formatting procedure that separately right-justifies the numbers and the units into adjacent columns?

    set term qt font "Courier,11"
    set size ratio -1
    set logscale xy
    
    set format x "%.0s%cΩ"    # no  space
    set format y "%.0s %cΩ"   # one space
    set xrange [1e-3:1e12]
    set grid x, y
    plot x
    
     

    Last edit: Ethan Merritt 2021-01-25
  • theozh

    theozh - 2021-01-25

    I see, number/unit alignment in axis labels is another viewpoint. Your monospace example with two spaces does not look good to me, but this is just a personal feeling.

    Here is a document from SI (BIPM):

    www.bipm.org/utils/common/pdf/si_brochure_8_en.pdf

    Section 5.3.3. Formatting the value of a quantity

    The numerical value always precedes the unit, and a space is always used to separate
    the unit from the number. Thus the value of the quantity is the product of the number
    and the unit, the space being regarded as a multiplication sign (just as a space
    between units implies multiplication).
    ...

    Well, it says 'a' and 'the' space... it doesn't say how wide this space is nor whether this could be two typographical spaces. However, nobody would write two spaces in a text.
    So, I would interpret this as one space, since there are not two multiplication signs.
    And (just my personal opinion) I would rate a single space (as in a text) higher than number/unit alignment in axes labels where as you say space and characters will become "variable" with proportional fonts anyway. How does (La)TeX do it? Donald Knuth should have a clear opinion on this...

     
  • Gabriel Dupras

    Gabriel Dupras - 2021-01-25

    According to the International System of Units (SI):

    The value of a quantity is written as a number followed by a space (representing a multiplication sign) and a unit symbol; e.g., 2.21 kg, 7.3×102 m2, 22 K.

    This is more than just a convention. It's a standard.

     
    • Ethan Merritt

      Ethan Merritt - 2021-01-25

      Thank you. It helps to have some justification stronger than "it looks better to me".

      I note, however, that the TeX implementation of SI units makes a distinction for tabular (vertically aligned) numbers. Here is a figure from the documentation for CTAN package siunitx. I see that format often in print, so it colors my expectations.

      Applied for 5.4 and 5.5

       
      • Gabriel Dupras

        Gabriel Dupras - 2021-01-25

        You have a point. Maybe people would like to align numbers and units in tick mark labels of the vertical axis.

        I've just given the latest patch a quick spin and looks like the width specifier is ignored when there is no unit prefix. If this bug could be fixed, then the width specifier could be used for alignment, like this: set format y ".0s %1cm"

        Anyway, with the following script

        print gprintf('%4.1s %c',  1) . 'm'
        print gprintf('%4.1s %0c', 1) . 'm'
        print gprintf('%4.1s %1c', 1) . 'm'
        print gprintf('%4.1s %2c', 1) . 'm'
        print gprintf('%4.1s %3c', 1) . 'm'
        
        print gprintf('%4.1s %c',  1e4) . 'm'
        print gprintf('%4.1s %0c', 1e4) . 'm'
        print gprintf('%4.1s %1c', 1e4) . 'm'
        print gprintf('%4.1s %2c', 1e4) . 'm'
        print gprintf('%4.1s %3c', 1e4) . 'm'
        

        I get

         1.0 m
         1.0 m
         1.0 m
         1.0 m
         1.0 m
        10.0 km
        10.0 km
        10.0 km
        10.0  km
        10.0   km
        

        but I think the correct output should be

         1.0 m
         1.0 m
         1.0  m
         1.0   m
         1.0    m
        10.0 km
        10.0 km
        10.0 km
        10.0  km
        10.0   km
        
         

        Last edit: Gabriel Dupras 2021-01-25
        • Ethan Merritt

          Ethan Merritt - 2021-01-25

          I did not think to test the width option "%nc". The patch I applied broke it. I pushed a revised fix for both 5.4 and 5.5 that honors the field width.
          Thanks for checking!

           
          • Gabriel Dupras

            Gabriel Dupras - 2021-01-26

            Thanks for the quick updates. I think this is still slightly off however. With the same script as in my previous comment, I'm getting

             1.0 m
             1.0 m
             1.0 m
             1.0  m
             1.0   m
            10.0 km
            10.0 km
            10.0 km
            10.0  km
            10.0   km
            

            instead of the expected output at the bottom of my previous comment. Lines 3, 4, and 5 are missing one space to the left of 'm'. All the other ones are correct.

            Basically I think that when there is no prefix, '%c' and '%0c' are correct but '%1c', '%2c', etc. are missing one space.

             
            • Ethan Merritt

              Ethan Merritt - 2021-01-26

              It looks correct to me. When you print a single character with "%1c", that character occupies the full width (==1). So there is no space in front of it. When the format is "%2c", the character occupies only 1 unit of the 2 that were requested, so a space is added. And so on.

               
              • Gabriel Dupras

                Gabriel Dupras - 2021-01-26

                When you print a single character with "%1c", that character occupies the full width (==1).

                I agree with this if a prefix is printed. For example, the output of gprintf('%1c',1e4') is k, which is one character. That's correct. But with gprintf('%1c', 1) there is no prefix to print. The output should still be one character wide (one space) but currently the output is an empty string.

                It's a bit hard to discuss invisible characters. I think it might be clearer with the script below. The comments show the output and the expected output.

                print gprintf('~%c~',  1)  # ~~   no space, that is correct
                print gprintf('~%0c~', 1)  # ~~   no space, that is correct
                print gprintf('~%1c~', 1)  # ~~   but should be ~ ~    (1 space)
                print gprintf('~%2c~', 1)  # ~ ~  but should be ~  ~   (2 spaces)
                print gprintf('~%3c~', 1)  # ~  ~ but should be ~   ~  (3 spaces)
                
                 
                • Ethan Merritt

                  Ethan Merritt - 2021-01-26

                  The gnuplot code is a thin wrapper around the standard C library sprintf() and the corresponding format specifier %c. Gnuplot chooses which single character to print, but the actual formatting is done by libc. Up until now gnuplot had been choosing a space (octal 040) as the single character to print. After patching the single character is NUL (ocal 000). So what you see is what libc provides.

                  I don't think this is an important enough issue to be worth writing or bypassing the standard library routines, so I will leave things as they are now (2nd version of patch).

                   
                  • Gabriel Dupras

                    Gabriel Dupras - 2021-01-26

                    Fair enough. I agree that this is a really small bug.

                     
  • Ethan Merritt

    Ethan Merritt - 2021-01-25
    • status: open --> pending-accepted
     
  • Ethan Merritt

    Ethan Merritt - 2021-06-02
    • status: pending-accepted --> closed-accepted
     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.