2011 뉴욕 지역 퀴즈 Decoding EDSAC Data 퀴즈 보고서
D ⋅ Decoding EDSAC Data
The world's first full-scale, stored-program, electronic, digital computer was the EDSAC (Electronic Delay Storage Automatic Calculator). The EDSAC had an accumulator-based instruction set, operating on 17-bit words(and 35-bit double words), and used a 5-bit teletypewriter code for input and output.
The EDSAC was programmed using a very simple assembly language: a single letter opcode followed by an unsigned decimal address, followed by the the letter 'F' (for full word) or 'D' (for double word). For example, the instruction "A 128 F"would mean "add the full word at location 128 to the accumulator", and would be assembled into the 17-bit binary value, 11100000100000000, consisting of a 5-bit opcode (11100="add"), an 11-bit operand (00010000000 = 128), and a single 0 bit denoting a full word operation (a 1 bit would indicate a double word operation).
Although arithmetic on the EDSAC was fixed point two's complement binary, it was not mere intger arithmetic (as is common with modern machines). The EDSAC hardware assumed a binary point between the leftmost bit and its immediate successor. Thus the hardware could handle only values in the range -1.0 ≤ x < 1.0. For example:
Value
Binary Representation
-1.0
10000000000000000
½
01000000000000000
¾
01100000000000000
-½
11000000000000000
As you can see, the largest possible positive value was:
01111111111111111 = 0.9999847412109375
and the smallest possible positive value was:
00000000000000001 = 2-16 = 0.0000152587890625
(This also happens to be the increment between successive values on the EDSAC).
By a curious coincidence(or an elegant design decision), the opcode for the add operation(11100) was the same as the teleprinter code for the letter 'A'. The opcode for subtract was the same as the teleprinter code for 'S'(01100), and so on. This simplified the programming for the assembler (which, incidentally, was a mere 31 instructions long). The EDSAC teleprinter alphabet was "PQWERTYUIOJ#SZK*?F@D!HNM&LXGABCV"(with 'P'=00000, 'Q'=00001, and so on, up to 'V'=11111)
Unfortunately, the EDSAC assembler had no special directives for data values. On the other hand, there was no reason that ordinary instructions couldn't be used for this, thus, an EDSAC programmer desiring to reserve space for the constant ¾ (represented as 01100000000000000) would use the instruction "S O F"and for ⅓ (which is approximately represented as 00101010101010101) "T 682 D", and so on.
Your job is to write a program that will translate EDSAC instructions into the appropriate decimal fractions.
Input
The first line of input contains a single integer P ( 1 ≤ P ≤ 1000 ) which is the number of data sets that follow. Each data set is a single line that contains N (the dataset number), followed by a space, followed by an EDSAC instruction of the form: c□d□s, where c is a single character in the EDSAC alphabet, d is an unsigned decimal number (0 ≤ d < 211), and s is either a 'D' or 'F'. Note: □ represents a single space.
Output
For each data set there is one line of output. It contains the data set number (N) followed by a single space, followed by the exact decimal fraction represented by the by the EDSAC instruction, including a minus sign (for negative values). The format for the decimal fraction is: sb.ddd...
, where s
is an optional minus sign, b
is either a 1 or 0, and d is any decimal digit (0-9). There must be at least 1 and at most 16 digits after the decimal point. Trailing zeros in the fraction must be suppressed.
Sample Input
Sample Output
13 1 P 0 F 2 I 0 F 3 & 0 F 4 ? 0 F 5 Q 1228 D 6 P 0 D 7 V 2047 D 8 * 2047 D 9 ? 0 D 10 P 256 F 11 V 1536 F 12 T 682 D 13 T 54 F
1 0.0 2 0.5 3 -0.5 4 -1.0 5 0.0999908447265625 6 0.0000152587890625 7 -0.0000152587890625 8 0.9999847412109375 9 -0.9999847412109375 10 0.0078125 11 -0.015625 12 0.3333282470703125 13 0.31414794921875
이 문제는 내가 직접 기계 중의 이진법으로 한 명씩 판단한 것이다.앞의 다섯 자리(1위, 뒤의 네 자리로 세분화), 중간 11위, 뒤의 한 자리를 나누어 처리한다.또 플러스와 마이너스도 각각 처리한다.
C 언어 소스 코드는 다음과 같습니다.#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
const char * code = "PQWERTYUIOJ#SZK*?F@D!HNM&LXGABCV";
int main (void)
{
int testcases;
int testcase;
char firstpart;
int secondpart;
char thirdpart;
int i;
unsigned short number;
long long result;
int sign;
long long current;
char final[100];;
scanf( "%d", &testcases );
while ( testcases -- )
{
scanf( "%d %c %d %c", &testcase, &firstpart, &secondpart, &thirdpart );
for ( i = 0; code[i] != '\0' ; i ++ )
{
if ( code[i] == firstpart )
break;
}
assert( code[i] != '\0' );
if ( i >= 0x10 )
{
number = i - 0x10 ;
sign = -1;
}
else
{
number = i;
sign = 1;
}
number <<= 12;
number += (secondpart << 1);
if ( thirdpart == 'D' )
number ++;
result = 0;
current = 152587890625;
if ( sign > 0 )
{
for ( i = 1 ; i <= 16 ; i ++ )
{
if ( (number & 1 ) == 1 )
{
result += current;
}
number >>= 1;
current <<= 1;
}
#ifdef _WIN32
sprintf( final, "0.%016I64d", result );
#else
sprintf( final, "0.%016lld", result );
#endif
}
else
{
number --;
for ( i = 1 ; i <= 16 ; i ++ )
{
if ( (number & 1 ) == 0 )
{
result += current;
}
number >>= 1;
current <<= 1;
}
#ifdef _WIN32
sprintf( final, "-0.%016I64d", result );
#else
sprintf( final, "-0.%016lld", result );
#endif
}
if ( !strcmp(final, "-0.0000000000000000" ) )
strcpy( final, "-1.0" );
else
{
if ( sign > 0 )
{
for ( i = 17; i > 2 ; i -- )
{
if ( final[i] == '0' )
final[i] = '\0';
else
break;
}
}
else
{
for ( i = 18; i > 3 ; i -- )
{
if ( final[i] == '0' )
final[i] = '\0';
else
break;
}
}
}
printf( "%d %s
", testcase, final );
}
return EXIT_SUCCESS;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSON
JSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다.
그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다.
저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
const char * code = "PQWERTYUIOJ#SZK*?F@D!HNM&LXGABCV";
int main (void)
{
int testcases;
int testcase;
char firstpart;
int secondpart;
char thirdpart;
int i;
unsigned short number;
long long result;
int sign;
long long current;
char final[100];;
scanf( "%d", &testcases );
while ( testcases -- )
{
scanf( "%d %c %d %c", &testcase, &firstpart, &secondpart, &thirdpart );
for ( i = 0; code[i] != '\0' ; i ++ )
{
if ( code[i] == firstpart )
break;
}
assert( code[i] != '\0' );
if ( i >= 0x10 )
{
number = i - 0x10 ;
sign = -1;
}
else
{
number = i;
sign = 1;
}
number <<= 12;
number += (secondpart << 1);
if ( thirdpart == 'D' )
number ++;
result = 0;
current = 152587890625;
if ( sign > 0 )
{
for ( i = 1 ; i <= 16 ; i ++ )
{
if ( (number & 1 ) == 1 )
{
result += current;
}
number >>= 1;
current <<= 1;
}
#ifdef _WIN32
sprintf( final, "0.%016I64d", result );
#else
sprintf( final, "0.%016lld", result );
#endif
}
else
{
number --;
for ( i = 1 ; i <= 16 ; i ++ )
{
if ( (number & 1 ) == 0 )
{
result += current;
}
number >>= 1;
current <<= 1;
}
#ifdef _WIN32
sprintf( final, "-0.%016I64d", result );
#else
sprintf( final, "-0.%016lld", result );
#endif
}
if ( !strcmp(final, "-0.0000000000000000" ) )
strcpy( final, "-1.0" );
else
{
if ( sign > 0 )
{
for ( i = 17; i > 2 ; i -- )
{
if ( final[i] == '0' )
final[i] = '\0';
else
break;
}
}
else
{
for ( i = 18; i > 3 ; i -- )
{
if ( final[i] == '0' )
final[i] = '\0';
else
break;
}
}
}
printf( "%d %s
", testcase, final );
}
return EXIT_SUCCESS;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.