Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Using 1-byte integers?

325 views
Skip to first unread message

Noob

unread,
Aug 26, 2015, 4:12:57 PM8/26/15
to
Hi,

I'm looking for a way to work with 1-byte integers in a portable way.
Right now, I know of INTEGER(INT8) or a CHARACTER. What's the
likelihood of INTEGER(INT8) not actually being available somewhere?

Thanks.

James Van Buskirk

unread,
Aug 26, 2015, 4:34:02 PM8/26/15
to
"Noob" wrote in message news:mrl6gs$tsj$1...@dont-email.me...

> I'm looking for a way to work with 1-byte integers in a portable way.
> Right now, I know of INTEGER(INT8) or a CHARACTER. What's the
> likelihood of INTEGER(INT8) not actually being available somewhere?

After that mob descended on Sun's compiler group's castle with
pitchforks and firebrands, zero.

Noob

unread,
Aug 26, 2015, 5:45:10 PM8/26/15
to
Thanks!

Ian Harvey

unread,
Aug 26, 2015, 5:47:45 PM8/26/15
to
On 2015-08-27 6:12 AM, Noob wrote:
> Hi,
>
> I'm looking for a way to work with 1-byte integers in a portable way.
> Right now, I know of INTEGER(INT8) or a CHARACTER.

It is an interesting question. Quite a few algorithms are written in
terms of manipulating "octets", and I find that doesn't map neatly
across to Fortran's intrinsic types.

There's also INTEGER(C_INT8_T), pulling C_INT8_T out of ISO_C_BINDING.

Depending on what you want to do, note that a character isn't an
integer. I think a reasonable guideline is that if you want an integer,
then use an integer - I would avoid (or isolate) if possible any games
where you store an object of one type in another object of different type.

What's the
> likelihood of INTEGER(INT8) not actually being available somewhere?

There is a 100% chance that it will *not* be available somewhere (the
world is a big place), but do you really care? On Fortran processors
that support the language revision that introduced INT8 (F2008), there's
a reasonable chance that they will support INT8.

Note that Fortran integers are always signed though. Depending on what
you want to do, that may complicate things. For example, algorithms
written in terms of octets often assume unsigned integer arithmetic on
those octets (or a group of octets) modulo the integer size.

Algorithms written in terms of octets also do a lot of bit manipulation
stuff. Perhaps this is a little esoteric given the Fortran processor
landscape of today, but note that the STORAGE_SIZE of an integer does
not have to be the same as the BIT_SIZE, and that the bit pattern that
results from a negative integer is processor dependent.

I'm interested in hearing the approach that others use in this area.

robert....@oracle.com

unread,
Aug 26, 2015, 6:29:42 PM8/26/15
to
On Wednesday, August 26, 2015 at 1:34:02 PM UTC-7, James Van Buskirk wrote:
> "Noob" wrote in message news:mrl6gs$tsj$1..
>
> > I'm looking for a way to work with 1-byte integers in a portable way.
> > Right now, I know of INTEGER(INT8) or a CHARACTER. What's the
> > likelihood of INTEGER(INT8) not actually being available somewhere?
>
> After that mob descended on Sun's compiler group's castle with
> pitchforks and firebrands, zero.

Oracle Solaris Studio Fortran does not yet implement the constant INT8 in ISO_FORTRAN_ENV, but it does support one-byte integers, both signed and unsigned. The declaration

INTEGER(SELECTED_INT_KIND(2)) I

should work for any processor that supports single octet signed integers.

Robert Corbett

Noob

unread,
Aug 26, 2015, 7:01:17 PM8/26/15
to
Dear Ian, thank you for your response.

I only need arrays of integers. Each integer will always be something
in the range [1:61] and I may need tens of millions of them in some
cases. This is why I thought of minimizing the storage size. From my
quick calculations, I predict having to allocate ~50-200MB, if I use
1-byte integers. The algorithms I'm implementing don't rely on any
particular integer size, it only must be able to hold a number as
large as 61.



Gordon Sande

unread,
Aug 26, 2015, 7:28:51 PM8/26/15
to
The desktop computers that I see being advertised seem to come with
8GB memory so 200MB is peanuts. You may want to pay more attention to the
memory width to get the most throughput. If you ask for a smaller size
than the natural size you may in fact slow things down. It depends!!

This is a nice example of where micro optimization may be harmful. Have a
happy time reading the detailed specs of your memory system. ;-) It will
undoubtedly be easier to just do the timing experiment. Most likely result
is that you can not tell the difference on even moderate sized problems.




Ian Harvey

unread,
Aug 26, 2015, 7:30:09 PM8/26/15
to
On 2015-08-27 9:01 AM, Noob wrote:
...
> I only need arrays of integers. Each integer will always be something
> in the range [1:61] and I may need tens of millions of them in some
> cases. This is why I thought of minimizing the storage size. From my
> quick calculations, I predict having to allocate ~50-200MB, if I use
> 1-byte integers. The algorithms I'm implementing don't rely on any
> particular integer size, it only must be able to hold a number as
> large as 61.

I'd just go with Robert Corbett's suggestion then. Even if you then end
up with a eight byte integer on some particularly exotic Fortran
processor, you are closer to having code that works than if you just
immediately give up if F2003/F2008 support isn't sufficient or a one
byte integer isn't available.

Either way, always use a named constant you control with a single point
of value definition for the kind, so that you can change your mind tomorrow.

Richard Maine

unread,
Aug 26, 2015, 9:52:13 PM8/26/15
to
Ian Harvey <ian_h...@bigpond.com> wrote:

> On 2015-08-27 6:12 AM, Noob wrote:

> > I'm looking for a way to work with 1-byte integers in a portable way.
> > Right now, I know of INTEGER(INT8) or a CHARACTER.
>

> I think a reasonable guideline is that if you want an integer,
> then use an integer - I would avoid (or isolate) if possible any games
> where you store an object of one type in another object of different type.

That's what I do (well, did back when I was coding for "real").
"Isolate" is such an important word for many things; it can help cover
for a lot of things. I tended to make a derived type, which I
inovatively called byte-type, with a single component. I had procedures
to get or set values so that the rest of the code didn't depend on the
type of the component. I had in mind that it would preferentially be an
8-bit integer, but could alternatively be a character, a 1-byte logical,
or a compiler-specific type such as byte.

Ended up that I always got by with 8-byte integers, declared, as Bob
suggests, with selected_int_kind, my coding being from long before
compilers could be counted on having even f2003 support, much less
f2008. (In fact, most of my basic code that I used for that dated back
to f90 days). I had access to the Sun compiler from their first f90
release, but I seem to recall that other things kept me from doing a Sun
port of most of my code back before they supported shorter integers.

Only one compiler was completely unworkable. I think it was an early
Salford compiler that refused to compile a derived type of one byte in
size no matter what. I needed my type to occupy exactly 1 byte because
it was used to pack data for portable files with precisely specified
layouts.

--
Richard Maine
email: last name at domain . net
dimnain: summer-triangle

glen herrmannsfeldt

unread,
Aug 27, 2015, 1:07:51 AM8/27/15
to
Richard Maine <nos...@see.signature> wrote:

(snip on 8 bit integer types)

> Only one compiler was completely unworkable. I think it was an early
> Salford compiler that refused to compile a derived type of one byte in
> size no matter what. I needed my type to occupy exactly 1 byte because
> it was used to pack data for portable files with precisely specified
> layouts.

Some years (SunOS 3.x days) I had to compile Metafont with the
SunOS Pascal compiler. For what should have been in 8 bit type,
it used 16 bits, so all files came out with two bytes where there
should have been one. A small C program fixes that.

But it helps that we only had to do it a reasonable number of times.

-- glen

robin....@gmail.com

unread,
Aug 27, 2015, 2:32:28 AM8/27/15
to
For portability, use CHARACTER.

Clive Page

unread,
Aug 27, 2015, 4:20:12 AM8/27/15
to
On 26/08/2015 22:47, Ian Harvey wrote:

> I'm interested in hearing the approach that others use in this area.

Well, in the past, I've used CHARACTER(LEN=1) together with the
functions CHAR and ICHAR for extracting and inserting integer values in
that type. The advantage is that you get an unsigned integer, i.e.
range 0 to 255. The disadvantage in theory is that the Standard by no
means guarantees that this will work. In practice, however,
byte-oriented machines have become the norm and I have not found a
compiler-machine combination on which this did not work.

For new software in the Fortran2008 era, though, I guess that using an
8-bit integer type would be better.


--
Clive Page

FX

unread,
Aug 27, 2015, 6:06:27 AM8/27/15
to
Your original query was [A]:

> I'm looking for a way to work with 1-byte integers in a portable way.

and this post specifies something almost entirely different [B]:

> I only need arrays of integers. Each integer will always be something
> in the range [1:61] and I may need tens of millions of them in some
> cases. This is why I thought of minimizing the storage size.

In Fortran, [B] is easier, and was possible since Fortran 95. The kind
type you want is

integer, parameter :: k = selected_int_kind(2)

which is guaranteed to represent integers between -99 and 99
(inclusively), and to be the smallest such kind (technically, the kind
with the smallest decimal exponent range).

Your requirement [A], finding a 1-byte (8-bit) integer kind, is slightly
more difficult:

- In Fortran 2008, you can use the named constant INT8 from
ISO_FORTRAN_ENV, which corresponds exactly to that.

- In Fortran 2003, if your compiler supports interoperability with C for
that specific type, you can use the C_INT8_T. This is required to
exist on POSIX systems, but is not a generic "standard C" requirement.

--
FX

Noob

unread,
Aug 27, 2015, 6:51:04 AM8/27/15
to
I see. I asked my first question in the way I did because I thought the
storage size of a variable declared with a kind parameter like
k = selected_int_kind(2) could be 8 bits or more, depending on what the
system has for me, and I didn't want the /or more/ part.

Thanks.

dpb

unread,
Aug 27, 2015, 9:31:34 AM8/27/15
to
On 08/27/2015 5:51 AM, Noob wrote:
...

> I see. I asked my first question in the way I did because I thought the
> storage size of a variable declared with a kind parameter like
> k = selected_int_kind(2) could be 8 bits or more, depending on what the
> system has for me, and I didn't want the /or more/ part.

The size _may_ be more, yes, but it's going to give you a result that
will hold the size of variable on any system. As noted by others, it's
possible there might not be an available type without the "or more" part
of the wish.

--

Richard Maine

unread,
Aug 27, 2015, 10:58:56 AM8/27/15
to
Yeah. When I did the stuff mentioned elsethread to get a 1-byte type,
the requirement that the type occupy exact 8 bits was fundamental to the
purpose. From the sounds of it, what you need is a perfect match for the
standard's selected_int_kind. You have a minimum range requirement and
you'd like the smallest available storage size that satisfies the range
requirement. That's what selected_int_kind does.

If selected_int_kind returns the kind for something larger than an 8-bit
integer, that most likely means that the compiler doesn't support an
8-bit integer at all. In that case, you have to decide whether your
specific needs are strong enough to merit hacking a more awkward
approach. There are options like storing 4 values in a 32-bit integer,
but that can be an awful lot of fuss. The need better justify it. As
Gordon mentioned, a few hundred megabytes isn't much in most
environments these days. Yes, it is enough to pay attention to, but I
doubt it is worth putting up with a lot of awkwardness in most cases
(and sometimes the slowdown that can accompany the awkwardness).

robin....@gmail.com

unread,
Aug 27, 2015, 11:17:16 AM8/27/15
to
On Thursday, August 27, 2015 at 8:06:27 PM UTC+10, FX wrote:
> Your original query was [A]:
>
> > I'm looking for a way to work with 1-byte integers in a portable way.
>
> and this post specifies something almost entirely different [B]:
>
> > I only need arrays of integers. Each integer will always be something
> > in the range [1:61] and I may need tens of millions of them in some
> > cases. This is why I thought of minimizing the storage size.
>
> In Fortran, [B] is easier, and was possible since Fortran 95. The kind
> type you want is
>
> integer, parameter :: k = selected_int_kind(2)
>
> which is guaranteed to represent integers between -99 and 99
> (inclusively), and to be the smallest such kind (technically, the kind
> with the smallest decimal exponent range).

This might give you an 8-bit storage, if the compiler implements it,
or it might give you 4 bytes of storage.

here's no guarantee that you will get any particular size of storage.

On the other hand, CHARACTER typically uses one byte of storage.

Over the past 35 years, I have found this to be portable over various compilers.

It's capable of storing anything you want: signed and unsigned integers --
even characters. :^)

glen herrmannsfeldt

unread,
Aug 27, 2015, 2:39:44 PM8/27/15
to
Noob <dont...@me.com> wrote:
> On 27/08/2015 07:04, FX wrote:

(snip)
>> - In Fortran 2008, you can use the named constant INT8 from
>> ISO_FORTRAN_ENV, which corresponds exactly to that.

>> - In Fortran 2003, if your compiler supports interoperability with C for
>> that specific type, you can use the C_INT8_T. This is required to
>> exist on POSIX systems, but is not a generic "standard C" requirement.


> I see. I asked my first question in the way I did because I thought the
> storage size of a variable declared with a kind parameter like
> k = selected_int_kind(2) could be 8 bits or more, depending on what the
> system has for me, and I didn't want the /or more/ part.

On a binary system, you never get the exact decimal digits you
ask for, and rarely the rounded up binary value.

selected_int_kind(2) asks for two decimal digits (-99 to +99),
selected_int_kind(3) asks for two decimal digits (-999 to +999),

On a processor using decimal (such as BCD) arithmetic you could
get the exact value, but not for binary.

-- glen




Noob

unread,
Aug 28, 2015, 9:21:23 AM8/28/15
to
On 27/08/2015 12:17, robin....@gmail.com wrote:
> On Thursday, August 27, 2015 at 8:06:27 PM UTC+10, FX wrote:
>> Your original query was [A]:
>>
>>> I'm looking for a way to work with 1-byte integers in a portable way.
>>
>> and this post specifies something almost entirely different [B]:
>>
>>> I only need arrays of integers. Each integer will always be something
>>> in the range [1:61] and I may need tens of millions of them in some
>>> cases. This is why I thought of minimizing the storage size.
>>
>> In Fortran, [B] is easier, and was possible since Fortran 95. The kind
>> type you want is
>>
>> integer, parameter :: k = selected_int_kind(2)
>>
>> which is guaranteed to represent integers between -99 and 99
>> (inclusively), and to be the smallest such kind (technically, the kind
>> with the smallest decimal exponent range).
>
> This might give you an 8-bit storage, if the compiler implements it,
> or it might give you 4 bytes of storage.
>
> here's no guarantee that you will get any particular size of storage.
>
> On the other hand, CHARACTER typically uses one byte of storage.
>
> Over the past 35 years, I have found this to be portable over various compilers.
>
> It's capable of storing anything you want: signed and unsigned integers --
> even characters. :^)
>

Right now I only wanted to minimize memory use but I already needed
1-byte storage when I was writing a small implementation of the PPM
image specification for the sake of learning. For that I used CHARACTER.
0 new messages