2017-07-10 5 views
1

J'ai un fichier binaire d'enregistrements de longueur fixe créé dans MS SSIS que j'ai besoin de lire dans SAS 9.4 64bit. Actuellement, le fichier est lu dans une étape de données en utilisant ce code:Lecture du fichier binaire dans SAS

data outputdata.(EOC=no 
        compress = yes 
        keep = a b c); 

length a $4.; 
length b 4.; 

infile "&inputfile." obs= 999999999 lrecl=308 recfm=F; 

input @5 a $4. 
     @9 b ib4. 
     @13 c rb4. 
; 
... 
... 
... 

Toutes les variables sont lues correctement dans l'ensemble de données de sortie, sauf c. c est un nombre à virgule flottante avec 2dp, valeur minimale 0,00 et valeur maximale 99,99. Dans le cas où c'est utile, c commence sa vie comme une valeur de VB.Net Single qui est convertie en binaire en utilisant BitConverter.GetBytes(Single) de VB.Net qui retourne un tableau de 4 octets. Ce tableau est ensuite écrit dans l'enregistrement binaire. D'après ce que je peux dire à partir de mes recherches sur le sujet rb4. est la bonne façon de lire une valeur à virgule flottante de 4 octets ('real'?) À partir d'un enregistrement binaire dans SAS donc probablement le problème réside dans la façon de formater cette valeur afin qu'elle apparaisse correctement dans l'ensemble de données en sortie. Je l'ai essayé ce qui suit:

format c rb2.2; 
format c 2.2; 
format c 4.; 

ainsi que les variations sur les valeurs des états de formats (par exemple format c 5.; etc.). Aucun des formats que j'ai essayés n'a abouti à quelque chose proche des valeurs correctes; la plupart aboutissent à des chiffres sous forme scientifique tels que 17E9.

c est un nouvel ajout au fichier binaire et est la seule variable 'réelle' contenue dans ce fichier, donc je n'ai pas d'exemple à partir duquel travailler. Je suis nouveau à SAS et j'ai hérité de ce projet, il y a de fortes chances que le problème soit assez fondamental!

Toute aide appréciée. Merci

+0

Est-ce SSIS/etc. sur une machine Windows? Et pour référence, 'best12.' devrait être un format parfaitement fin à utiliser (ce qui est le format par défaut si vous ne mentionnez pas un format). Votre problème est entrée informat, pas le format de sortie, probable. – Joe

+0

D'un balayage rapide des docs pour la fonction VB.NET et le format RBw.d de SAS, je dirais que RB4. est un choix raisonnable, mais FLOAT4. peut-être mieux - voir la note sur les flotteurs IEEE ici: http://support.sas.com/documentation/cdl/en/leforinforref/69823/HTML/default/viewer.htm#p0gnfpn5157n9un10ds13qr0tarj.htm.Il serait également intéressant de vérifier l'ordre des octets dans le fichier binaire source - vous pourriez lire la valeur avec la mauvaise endian-ness. Essayez d'ouvrir le fichier dans un éditeur hexadécimal et de convertir les octets que vous trouvez avec ceci: https://www.h-schmidt.net/FloatConverter/IEEE754.html –

+2

Pour l'aide la plus utile, vous pouvez le lire avec $ 4 et faire 'mettre c $ hex4.' et poster quelques lignes, avec la valeur que vous pensez qu'il devrait être, et ce que' $ hex4' montre comme. Chris pourrait avoir raison sur les questions endian, bien que SSIS devrait être sur Windows je m'attendrais ... – Joe

Répondre

1

En répétant mes commentaires comme une réponse ...

Vous devez utiliser FLOAT4. pour lire une valeur qui a été écrite par la fonction VB.NET BitConverter.GetBytes(Single). Le RB4. informat lit quatre octets d'entrée comme s'il s'agissait d'une valeur à virgule flottante à double précision tronquée, mais la sortie de la fonction VB.NET est une valeur à virgule flottante simple précision, alias 'float', qui n'est pas la même chose .

La note sur la page de documentation de SAS pour la FLOAT format explique:

Le informat FLOATw.d est utile dans des environnements d'exploitation où une valeur flottante est pas le même que tronqué double.

Sur les systèmes grand système IBM, un nombre à virgule flottante de quatre octets est identique à un nombre à virgule flottante de huit octets tronqué. Toutefois, dans les environnements d'exploitation qui utilisent la norme à virgule flottante IEEE, tels que les environnements d'exploitation IBM PC et la plupart des plates-formes UNIX, un nombre à virgule flottante de quatre octets n'est pas identique à un double tronqué. Par conséquent, le RB4. informat ne produit pas les mêmes résultats que FLOAT4. Les représentations à virgule flottante autres que IEEE peuvent avoir cette même caractéristique. Valeurs lues avec FLOAT4. proviennent généralement d'un autre programme externe qui s'exécute dans votre environnement d'exploitation.

+0

Excellent, merci – Spink