'Postscript: how to convert a integer to string?

In postscript , the cvs *operator* is said to convert a number to a string. How should I use it ? I tried :

100 100 moveto
3.14159 cvs show

or

100 100 moveto
3.14159 cvs string show

but it didn't work.

Any help ?



Solution 1:[1]

Try 3.14159 20 string cvs show.

string needs a size and leaves the created string on the stack. cvs needs a value and a string to store the converted value.

If you're doing lots of string conversions, it may be more efficient to create one string and reuse it in each conversion:

/s 20 string def
3.14159 s cvs show

Solution 2:[2]

tldr;

A common idiom is to use a literal string as a template.

 1.42857
(       ) cvs show

more...

You can even do formatted output by presenting cvs with various substrings of a larger string.

%0123456.......
(2/7 =         ) dup 6 7 getinterval
2.85714 exch cvs pop show

But the Ghostscript Style Guide forbids this. And it's pretty much the only published Postscript Style Guide we have. (A discussion about this in comp.lang.postscript.) So a common recommendation is to allocate a fresh string when you need it and let the garbage collector earn its keep.

4.28571 7 string cvs show

Freshly allocating a string can be very important if you're wrapping this action in a procedure.

/toString { (          ) cvs } def
%    vs
/toString { 10 string cvs } def

If you allocate a fresh string, then the enclosing procedure can be treated as a pure function of its inputs. If you use an embedded literal string as the buffer, then this resulting string is state-dependent and will be invalidated if the generating procedure is run again.

too much, don't do this...

As a last resort, the truly lazy hacker will hijack =string, the built-in 128-byte buffer used by = and == to output numbers (using, of course, our friend cvs). This is interpreter-specific and not portable according to the standard.

5.71428 =string cvs show

And if you like that one, you can combine it with ='s other trick: immediately evaluated names.

{ 7.14285 //=string cvs show }   % embed =string in this procedure

This shaves that extra microsecond off, and makes it much harder to interactively inspect the code. Calling == on this procedure will not reveal the fact that you are using =string; it looks just like any other string.

Using =string in this manner inherits all the state-dependency problems described in the last section, ramped up a notch because there's only one =string buffer. And it adds a portability issue to boot, since =string is non standard -- albeit available in historical Adobe implementations and Ghostscript -- it is a legacy hack and should be used only in situations where a legacy hack is appropriate.


something else, no one (here) asked for...

One more trick for the bag, from a post by Helge Blischke in comp.lang.postscript. This is a simple way to get a zero-padded integer.

/bindec         % <integer> bindec <string_of_length_6>
{
        1000000 add 7 string cvs 1 6 getinterval
}bind def 

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2