'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 |