Program yang menambahkan semua bilangan asli dan hasil -1/12 [ditutup]


53

Seperti yang Anda ketahui ada fakta menyenangkan matematis bahwa jika Anda menambahkan semua bilangan asli, Anda akan mendapatkan ... -1/12 (lihat Wikipedia di sini) .

Tentu saja ini hasil yang sangat aneh dan tidak dapat diperoleh dengan hanya menambahkan satu angka diikuti oleh yang lain, tetapi beberapa trik matematika khusus.

Namun tugas Anda adalah menulis sebuah program, yang terlihat seperti mencoba untuk menambahkan semua bilangan asli, tetapi ketika Anda menjalankannya - ia mengembalikan -1/12.

Dalam pseudocode mungkin terlihat seperti ini:

result  = 0;
counter = 1;
while(true) {
  result  += counter;
  counter ++;
}
println(result);

Anda dapat melakukan ini dengan cara apa pun yang Anda suka - Anda dapat mengeksploitasi beberapa buffer overflow, bermain dengan kesalahan yang dilemparkan sementara beberapa variabel menjadi terlalu besar atau hanya menyembunyikan hal penting di sepanjang kode dengan cara yang cerdas. Satu-satunya syarat adalah bahwa kode tersebut harus pada awalnya terlihat seolah-olah ia mencoba untuk menambahkan semua bilangan asli dan ketika menjalankannya mengembalikan -1/12 (dalam format apa pun, itu mungkin desimal, biner, teks, ascii art apa pun).

Tentu saja kode dapat berisi lebih banyak, daripada yang ditunjukkan di atas, tetapi harus cukup jelas, untuk menipu pembaca.

Ini adalah kontes popularitas - pilih ide yang paling cerdas!


2
Memperbaiki tag Anda: jika ini adalah kontes popularitas, itu tidak mungkin golf kode, dan kami memiliki tag curang untuk tantangan seperti "menulis kode yang terlihat seperti x tetapi tidak y". Bagaimanapun, ini adalah tantangan yang cukup baik untuk pendatang baru! :)
Martin Ender

2
@ m.buettner - terima kasih telah mengedit tag, ya, saya baru di sini, jadi saya tidak mengetahui semua tag. Saya akan mencoba mengikuti aturan!
Paweł Tokarz

3
Mengapa semua jawaban beserta pertanyaannya baru saja diturunkan? Downvoter: silakan tinggalkan komentar.
arshajii

7
Baris pertama tidak sepenuhnya benar, tergantung pada interpretasi Anda math.stackexchange.com/questions/39802/…
qwr

3
Saya memberikan suara untuk menutup pertanyaan ini sebagai di luar topik karena tantangan curang tidak lagi pada topik di situs ini. meta.codegolf.stackexchange.com/a/8326/20469
cat

Jawaban:


38

C

Harus bekerja pada platform di mana keduanya sizeof(float)dan sizeof(int)4 dan mengikuti standar IEEE floating point (saya kira).

Versi 1:

#define toFloat(x) (*(float*)&x)
#define ABS(x)     (x<0 ? (-x) : x)
#include <stdio.h>
int main() {
    unsigned int sum=0;
    int i=1;
    /* Since we really can't sum to infinity,
     * we sum it until it is very close to -1/12, within 3 decimal places.
     * Need to convert sum to float since -1/12 is not int                 */
    while(!(ABS(toFloat(sum) + 1./12) <= 0.001)) {
        sum+=i;
        i++;
    }
    printf("%.3f\n", toFloat(sum));
    return 0;
}

Keluaran: -0.083

Penjelasan:

Bukan jawaban yang sangat menarik, tetapi dengan komentar yang menyesatkan.

Jumlah 1 hingga 79774 adalah 3181985425, yang memiliki representasi biner yang sama dengan -0.082638867199420928955078125 ketika ditafsirkan sebagai floatbukan unsigned int.

Catatan yang !(abs<=0.001)digunakan bukan abs>0.001untuk menghindari berhenti dari loop ketika jumlahnya mencapai 2139135936 (NaN dalam float). (Terima kasih kepada @CodesInChaos karena menyarankan gagasan ini alih-alih isNaNcek independen .)

Terima kasih khusus kepada @Geobits untuk gagasan mengakhiri loop dengan membandingkan jumlah dan bukan penghitung.

Sunting: Versi 2

#include <stdio.h>
const float inf = 1./0.;
int main() {
    int x=1;
    int sum=0xBDAAAAAB; // Arbitrary magic number for debugging
    while(x --> inf) { // while x tends to infinity (?)
        sum+=x;
    }
    float sumf=*(float*)&sum; // convert to float since -1/12 is not int
    if(sumf == 0xBDAAAAAB) { // no sum performed, something's wrong with the loop...
        fprintf(stderr, "sum is unchanged\n");
        return -1;
    }
    printf("%f\n", sumf);
    return 0;
}

Keluaran: -0.083333

Penjelasan:

Menggunakan sama int-to- floattrik, tetapi dengan --> "cenderung" operator sini. Karena setiap angka lebih kecil dari tak terhingga maka loop tidak akan dieksekusi sekalipun.

Setelah mengkonversi ke floatitu dibandingkan dengan angka intajaib (yaitu -0,83333 dibandingkan dengan 0xBDAAAAAB, atau 3182078635), yang tentu saja berbeda.


3
buat #define INFINITY di atas dan ganti i <INFINITY
ojblass

2
Cara menarik untuk keluar dari lingkaran harus dipertimbangkan.
ojblass

Untuk apa nilainya, dalam hex 79776adalah 137A0, yang mana ((int) "\rz") << 4. Tidak yakin seberapa bermanfaat itu,
durron597

3
Anda bisa mendefinisikan epsilon untuk keluar dari loop. Penjelasan: "karena kita tidak dapat lari hingga tak terbatas, kita akan keluar setelah konvergen pada -1/12 dalam margin kesalahan floating point" atau serupa. Anda harus memeriksa nilai float setiap iterasi, tetapi itu akan menghilangkan nilai 'infinity' yang aneh.
Geobits

1
Dalam kode pertama Anda bisa menggunakan while(!(abs<delta))bukan while(abs>delta)untuk menjatuhkan cek NaN.
CodesInChaos

20

Python

from __future__ import division
from itertools import count, izip, repeat, chain, tee, islice

def flatten(iterable):
  "Flatten one level of nesting."
  return chain.from_iterable(iterable)

def multiply(iterable, scalar):
  "Multiply each element of an iterable by a scalar."
  for e in iterable:
    yield e * scalar

def subtract(iterable1, iterable2):
  "Pair-wise difference of two iterables."
  for e, f in izip(iterable1, iterable2):
    yield e - f

def add(iterable1, iterable2):
  "Pair-wise sum of two iterables."
  for e, f in izip(iterable1, iterable2):
    yield e + f

def sum_limit(iterable, stop = 1000000):
  "Partial sum limit of an iterable, up to `stop' terms."
  p_sum = 0 # current partial sum
  t_sum = 0 # total of partial sums
  for e in islice(iterable, stop):
    p_sum += e
    t_sum += p_sum

  # return average of partial sums
  return t_sum / stop

# All natural numbers
n = count(1)

# The same range multiplied by 4
n4 = multiply(count(1), 4)

# Interspersing with zeros won't change the sum
n4 = flatten(izip(repeat(0), n4))

# Subtracting 4n - n results in 3n
n3 = subtract(n4, n)

# Make two clones of this range
n3a, n3b = tee(n3)

# Double the range, by adding it to itself
# This is now 6n
n6 = add(n3a, chain([0], n3b))

# Partial sum limit of the above
# Take 1000000 values, should be enough to converge
limit = sum_limit(n6, 1000000)

# Divide by 6 to get the sum limit of n
print limit / 6

Hasil:

-0.0833333333333

Jadi apa masalahnya?

Caranya adalah: ini adalah perhitungan yang valid.


18

Mathematica

\:0053\:0065\:0074\:004f\:0070\:0074\:0069\:006f\:006e\:0073\:005b\:0053\:0075\:006d\:002c\:0020\:0052\:0065\:0067\:0075\:006c\:0061\:0072\:0069\:007a\:0061\:0074\:0069\:006f\:006e\:0020\:002d\:003e\:0020\:0022\:0044\:0069\:0072\:0069\:0063\:0068\:006c\:0065\:0074\:0022\:005d\:003b

Sum[n, {n, 1, Infinity}]
-1/12

(Catatan: menempelkan ini ke notebook Mathematica kemungkinan akan mengungkapkan apa yang terjadi.)


Apa yang terjadi di sini adalah bahwa kita sedang menyiapkan default regularisasi dari Summenjadi Dirichlet regularisasi (dikodekan dalam baris pertama - catatan yang Mathematica memungkinkan literal unicode di sumbernya), sehingga baris kedua, yang di luar konteks terlihat seperti itu akan menghasilkan infinity, akhirnya menghasilkan nilai yang diatur -1/12.


3
Saya cukup yakin ini curang karena Anda memberi tahu Mathematica untuk menggunakan regularisasi yang diperlukan untuk membuat penjumlahan bekerja.
Kyle Kanos

4
@KyleKanos Kenapa itu curang?
arshajii

2
Saya tahu ini bukan kode golf, tetapi hanya tip: Anda dapat memotong empat karakter dan langsung menambahkan 68+{0,37,46,37,31,36,40,33,48}, karena Plusmemiliki Listableatribut. Secara pribadi, saya menemukan ini lebih idiomatis.
David Zhang

3
@ Rarshjii: itu curang karena Anda seharusnya menyembunyikan fakta bahwa kode tersebut menyesatkan. Menggunakan paket yang disebut 'regularisasi' tidak menyembunyikan ini sama sekali. -1 dari saya.
Kyle Kanos

1
@ Rajiajii: Itu menyembunyikannya lebih sedikit & saya sudah membatalkannya.
Kyle Kanos

10

C

Dengan baik format jawabannya sebagai -1/12, bukan 0.8333.

#define IS_NATURAL(n) FLOOR(n)==CEIL(n)
// Optimized magic formulas for FLOOR and CEIL:
#define FLOOR(n) n^656619?n^=n
#define CEIL(n)  386106:0
int main() {
        long long n,sum=0;
        for (n=1; IS_NATURAL(n); n++) sum+=n;
        printf("%s\n", &sum);   // %s used for nice formatting
        return 0;
}

Bagaimana itu bekerja?

Jumlah semua angka hingga 656618, tidak termasuk 386106. Ini memberikan 215573541165.
Ketika ditafsirkan sebagai string, pada platform endian kecil, Anda mendapatkan -1/12.


7

Brainfuck

+ [ [->+>+<<] > [-<+>] <+ ]
--------------------------------------------------------------------------------
Evaluate $\sum_{i=1}^\infty i$
--------------------------------------------------------------------------------
Memory Layout:
i > copy of i > sum
--------------------------------------------------------------------------------
Happy today? ---.+++ +.- -.+ +.+
Please vote me up.
--------------------------------------------------------------------------------

Kode hanya mengevaluasi 1 + 2 + 3 + ...

... sampai i == 256dan melimpah terjadi, dengan asumsi ukuran sel 8-bit. Setelah itu, imenjadi 0, loop berakhir dan komentar berikut dieksekusi.


Ini tidak masuk akal. Sebagian besar penafsir membungkus serta fakta bahwa Anda mengklaimnya mengevaluasi 1 + 2 + 3 + ...yang berarti 256 harus berbentuk segitiga i == 256seperti yang Anda klaim juga, tetapi 256 bukan angka segitiga. Juga, di mana output kode Anda -1/12?
Timtech

@Timtech Loop tidak berhenti. Adalah penghitung yang meluap, bukan jumlahnya. Hanya satu masalah kecil: itu output 1/12bukan -1/12(Selamat hari ini? + .- - .+ + .+ Silakan pilih saya .) Keempat .ini untuk keluaran.
ace_HongKongIndependence

@ace Jika itu adalah penghitung, akan ada dua opsi: 1) Jika sel-sel membungkus, maka tidak akan ada overflow ATAU 2) jika sel-sel tidak membungkus, maka jumlah akan meluap jauh sebelum penghitung bahkan mendekati 256.
Timtech

@ace Bagaimana saya bisa membuat kesalahan konyol itu? Saya memperbaikinya, tetapi sekarang tampaknya kurang curang.
johnchen902

1
@Timtech Cells membungkus, jadi imenjadi nol ketika sampai 256(itulah yang saya maksud dengan melimpah). Setelah titik ini, loop luar berakhir, dan baris berikut (yang tampak seperti komentar) dieksekusi, maka output dari -1/12.
johnchen902

6

Hanya menambahkan sedikit kebingungan yang lebih baik dari meninggalkan loop ke jawaban ace.

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

void handler(int trapId)
{
  unsigned int sum=3182065200L;
  printf("%.3f\n",*(float*) &sum);
  exit(0);
}

int main (void)
{
    unsigned int sum=0;
    int i=0;
    float average = 0.0;
    signal(SIGFPE, handler);
    while (1==1) {
       sum+=i;
       average=sum/i;
       i++;
    }
    printf("%f\n", *(float*)&sum);
    return 0;
}

Tips tidak ada luapan ...

Saya membaginya dengan 0 sebelum saya menambah variabel saya menendang pengecualian handler


Tambahkan beberapa komentar!
Navin

3
Dia hanya terus menjumlahkan sampai saya menjadi nol lagi karena melimpah, pada titik mana average=sum/i;memberikan SIGFPE, tertangkap oleh handler, mencetak -1/12.
mulai

bukankah menambahkan komentar melawan semangat licik?
ojblass

1
@ojblass Bergantung pada seberapa liciknya komentar tersebut. ;-)
Daniel Wagner

8
unsigned int sum=3182065200L; printf("%.3f\n",*(float*) &sum);adalah hadiah mati bahwa ada sesuatu yang terjadi di sana, dan melihat bahwa ada di handler untuk SIGFPE membuat ini terlalu jelas untuk seleraku.
hvd

4

Perl 6

Ini menghitung jumlah menggunakan fungsi zeta. Saya akan menggunakan [+] 1..*(jumlah semua angka antara 1 dan tak terbatas), kecuali yang berjalan dalam waktu yang tak terbatas.

use v6;

# Factorial function.
sub postfix:<!>($number) {
    return [*] 1 .. $number;
}

# Infinite list of bernoulli numbers, needed for zeta function.
my @bernoulli := gather {
    my @values;
    for ^Inf -> $position {
        @values = FatRat.new(1, $position + 1), -> $previous {
            my $elements = @values.elems;
            $elements * (@values.shift - $previous);
        } ... { not @values.elems };
        take @values[*-1] if @values[*-1];
    }
}

# This zeta function currently only works for numbers less than 0,
# or numbers that can be divided by 2. If you try using something else,
# the compiler will complain. I'm too lazy to implement other cases of
# zeta function right now.
#
# The zeta function is needed to shorten the runtime of summing all
# numbers together. While in Perl 6, [+] 1..* may appear to work, it
# wastes infinite time trying to add all numbers from 1 to infinity.
# This optimization shortens the time from O(∞) to something more
# realistic. After all, we want to see a result.

multi zeta(Int $value where * < 0) {
    return @bernoulli[1 - $value] / (1 - $value);
}

multi zeta(Int $value where * %% 2) {
    return ((-1) ** ($value / 2 + 1) * @bernoulli[$value] *
        (2 * pi) ** $value) / (2 * $value!);
}

# 1 + 2 + 3 + ... = (-zeta -1)
#
# Reference: Lepowsky, J. (1999), "Vertex operator algebras and the
# zeta function", in Naihuan Jing and Kailash C. Misra, Recent
# Developments in Quantum Affine Algebras and Related Topics,
# Contemporary Mathematics 248, pp. 327–340, arXiv:math/9909178
say (-zeta -1).nude.join: "/";

Haha, saya berpikir untuk mengirim penjumlahan sederhana dan mengklaim bahwa itu akan berhasil, tetapi Anda harus menunggu waktu tak terbatas sebelum itu akan dicetak. Senang melihat orang lain juga berpikir begitu.
Kyle Kanos

4

Jawa

public class Add {
    public static void main(final String... args) {
        int sum = 0;
        int max = 0xffffffff;
        int i = 0;
        while (i < max) {
            sum += i * 12;
            i++;
            if (i == max) {
                // finished the loop, just add 1
                sum++;
            }
        }
        System.out.println(sum);
    }
}

Ini menambahkan semua angka dari 0 hingga nilai maksimum, dikalikan 12, dan juga menambahkan 1 di akhir. Hasilnya adalah 0, oleh karena itu jumlah angka harus (0 - 1) / 12.

Penjelasan:

0xffffffff == -1, loop tidak dieksekusi sama sekali


3

Rubi

print "Using Ruby #$RUBY_PLATFORM-.#$RUBY_VERSION#$."

BUFF_SIZE = 3
STREAM = STDOUT.to_i

if STREAM.<<(BUFF_SIZE).display{:error}
  abort "Cannot write to stream"
end

i = 0
sum = 0

until STREAM.|(BUFF_SIZE).display{:eof}
  sum += i
  i += 1
end

STREAM.<<(sum)

Demo

Oke, semantik output dan sintaksis yang seharusnya di sini tidak masuk akal, tapi mungkin itu tidak terlihat secara sepintas.

Perhatikan juga bahwa ini sebenarnya tidak tergantung pada Platform dan Versi Ruby. Itu tergantung pada beberapa konstanta lain yang didefinisikan seperti yang diharapkan.


3

C

#include "stdio.h"

// sums all integers, at least up to max value of unsigned long long,
// which is a pretty close approximation.
int main()
{

    double sum = 0.0;
    double stop_value = -0.08333333333;
    unsigned long long count = 0;

    while(1)
    {
        sum = sum + (double)count++;

        // know what the stop_value in hex is?!??/
        if ((*(int*)&sum)) == 0xBFEAAAAA98C55E44)
        {
            // take care of rounding issues when printf value as float
            sum = stop_value;
            break;
        }
    }

    printf("sum: %f\n", sum);

    return 0;

}

Dalam rangka menangani (hampir) jumlah tak terbatas dalam jumlah waktu yang wajar, kompilasi dengan opsi berikut untuk beberapa optimisasi kompiler (diperlukan):

$ gcc -trigraphs sum.c

Output sampel:

$ ./a.out
$ sum: -0.83333
$

1
Jika Anda ingin tahu cara kerjanya, baca file .S.
Yosua

8
Bendera kompiler Anda memberikan segalanya ...
ace_HongKongIndependence

3
"Celah" standar yang tidak lagi lucu - ??/Trik trigraph telah lama berhenti menjadi pintar. :(
doppelgreener

Terima kasih atas tautannya, itu menjelaskan banyak hal. Apakah ada tautan ke FAQ di mana saja, atau apakah saya harus mencarinya setiap waktu?

@tolos Anda bisa menikmatinya, atau itu satu-satunya pertanyaan di bawah tag meta [ faq ], atau menemukannya melalui FAQ Komunitas .
doppelgreener

3

Jawa

int sum = 0;
long addend = 0L;
while (++addend > 0){
    sum += addend;
}
System.out.println(sum == -1/12);

Secara teori, ini akan dicetak true. Namun, saya pikir komputer saya akan hancur menjadi debu sebelum selesai menjalankannya.


1
Mengapa itu seharusnya benar? Mengapa Anda berharap jumlahnya akan mencapai -1/12?
Paweł Tokarz

@ PawełTokarz Saya bukan pakar Java, jadi saya tidak bisa memastikannya, tetapi perlu dicatat bahwa karena Java menggunakan divisi integer -1/12sebenarnya nol. Jadi saya menganggap itu adalah semacam perilaku overflow yang menyebabkan loop berakhir dan kebetulan summeluap ke nol?
ace_HongKongIndependence

Ya, overflow akan membuat loop berhenti ketika mencapai maksimum long. Alam semesta mungkin tidak akan ada lagi saat itu, tetapi ini hanya teoretis, bukan? Dan ya, 32 bit terbawah dari sumsemuanya akan menjadi nol - itulah mengapa penting untuk summenjadi int, bukan a long. Tentu saja, seperti yang dikatakan @ace, Java menggunakan divisi integer untuk mengevaluasi -1/12, jadi nol.
Dawood mengatakan mengembalikan Monica

1
long.MAX_VALUE adalah 9.223.372.036.854.775.807. Itu besar, tetapi peningkatan hanya 1 juta kali per detik akan membawa Anda ke sana hanya dalam beberapa ratus ribu tahun. Anda hanya perlu sekitar 4 miliar kenaikan per detik untuk menyelesaikannya dalam masa hidup manusia. Kita tidak sedang membicarakan rentang waktu "akhir jagat raya", di sini, kecuali Anda tahu sesuatu yang tidak Anda bagikan dengan kita semua.
user19057

1
@ user19057 Terima kasih atas koreksinya. Anda tentu saja benar, walaupun saya ingin tahu mengapa menurut Anda alam semesta akan bertahan lebih dari 100.000 tahun lagi. Bagaimanapun, saya tidak akan duduk-duduk menunggu program saya selesai berjalan. Ada rumput untuk saya perhatikan tumbuh.
Dawood mengatakan mengembalikan Monica

3

Jawa

import ȷava.math.BigDecimal;
import static ȷava.math.BigDecimal.ONE;
import static ȷava.math.BigDecimal.ZERO;
import static ȷava.math.BigDecimal.truе;

public class Test {

    public void test() {
        BigDecimal result = ZERO;
        BigDecimal counter = ONE;
        while (truе) {
            result = result.add(counter);
            counter = counter.add(ONE);
        }
        System.out.println(result);
    }

    public static void main(String args[]) {
        try {
            new Test().test();
        } catch (Throwable t) {
            t.printStackTrace(System.err);
        }
    }
}

Bagaimana itu bekerja:

Java menggunakan pengkodean UTF-8 untuk semuanya. Saya menggunakan truеdengan Cyrillic Ye di ujung bukannya biasa 'e' (terima kasih kepada @CodesInChaos) yang merupakan static booleandijalankan untuk false. Ada import ȷava.math.BigDecimal;dengan j dotless bukannya definisi import java.math.BigDecimal; saya dan untuk menyebutkan dua hack jelas.ȷava.math.BigDecimalpublic static boolean truе = false;public String toString() { return "-1/12"; }

Seandainya saya bisa memposting ini sebagai spoiler tapi saya tidak tahu caranya. Inilah sisa kode yang tersembunyi secara tersembunyi.

// Note that the ȷ in `ȷava` below is NOT a real j.
package ȷava.math;

public class BigDecimal {

    // true is actually false! Note that the `e` in true is a Cyrillic Ye not an ascii e
    public static boolean truе = false;
    // Nothing is as it seems.
    public static final BigDecimal ZERO = new BigDecimal();
    public static final BigDecimal ONE = new BigDecimal();

    @Override
    public String toString() {
        return "-1/12";
    }

    public BigDecimal add(BigDecimal b) {
        // Do nothing.
        return this;
    }
}

Ŧrue / true terlihat jelas, tetapi perbedaan antara ȷava dan java sangat kecil sehingga saya harus membaca komentar beberapa kali untuk mengetahui titik ini!
Paweł Tokarz

1
@OldCurmudgeon Saya pikir ada yang sangat mirip untuk e dalam alfabet Cyrillic: Ye (Cyrillic)
CodesInChaos

1
Jika saya tidak salah, Anda memposting kode yang tidak lengkap. Jika Anda mengimpor paket non-standar, Anda juga harus memposting kodenya.
ugoren

1
The cyryllic 'e' cukup keren untuk membuat hal-hal tidak terbaca. Bayangkan: if (true! = True) {return true} else {return true}; : D
Paweł Tokarz

1
@Andrew G true!
Paweł Tokarz

2

Tidak ada solusi Haskell, tidak dapat diterima!

Kita dapat menggunakan daftar Haskell yang tak terbatas untuk mendapatkan jawaban yang tepat!

Haskell:

import Data.Bits
import Data.Char
import Data.Ratio
import Data.Tuple
import Control.Applicative
import Control.Arrow

{-# LANGUAGE SingleLineComment "$" #-}

main = print . showAnswer ( sum [1,2..] )
     $ prints "Summation of Natural Numbers"

showAnswer _ = id

prints = uncurry (%) . first negate
       . uncurry quotRem . flip
       ( (***) <$> id <*> id     )
       ( second negate twinPrime )
       <$> (+) . flip shiftR 2
       . ord . head
       where twinPrime = (5,7)

Solusi cukup lurus ke depan ketika Anda memperhitungkan panah ....

Jadi apa masalahnya?

Tidak ada ekstensi bahasa untuk menentukan satu baris komentar


2

C

#include <stdio.h>

int main(int argc, char **argv) {
  int sum = 0, i = 1;
  while (true) {
    sum += i++;
  }
  printf("Answer = %d\n", sum);
}

Menurut standar C, ini bisa sangat baik dicetak Answer = -1/12karena akan ada limpahan bilangan bulat yang ditandatangani yang merupakan perilaku tidak terdefinisi. Menemukan kompiler yang akan melakukan ini dibiarkan sebagai latihan untuk pembaca.


kode ini tidak akan pernah mencapaiprintf
Bogdacutu

5
Saya lebih suka jawaban yang biasanya menghasilkan output yang diperlukan, bukan hanya "mengizinkannya".
Paŭlo Ebermann

2

Mathematica

I I/Row[{##}]&@@

 (
  result = 0;
  counter = 1;
  while (true); {
   counter++,
   result += counter}
  )

masukkan deskripsi gambar di sini


2
Maukah Anda memberikan penjelasan tentang apa yang terjadi di sini?
ace_HongKongIndependence

Haha, cukup lucu, dan bisa menjadi bahan yang baik untuk menguji apakah seorang pemula Mathematica telah memahami sintaksis dasar atau tidak!
xzczd

1

Python 3.x

Agak baru di sini. Ada tips?

import sys
from string import digits as infinity

#function to add two numbers
def add(num1, num2):
    return num1 + num2


#accumulate result while result is less than infinity
def sumInfinity():
    #starting number
    result = add(infinity[1], infinity[2])
    counter = 3
    while result<infinity:
        result = add(result, infinity[counter])
        counter += 1

    return result

#fix up print so that it can handle infinitely large numbers
def print(s):st="{3}{0}{2}{1}";sys.stdout.write(st.format(infinity[1],s,"/","-"))

print(sumInfinity())

1

JavaScript (ECMAScript 6)

result  = 0;
counter = 1;
one     = 1;

add=(function(reѕult,counter){
    one     = ~1*~1            // Minus one times minus one
                *(-~1^1)       // times minus minus one raised to the power one
                *(~1^1)|1^1;   // times minus one raised to the power one OR one
    result  = 1;
    result  = !reѕult/one; // Reset result to zero.
    return (result,counter)=>(result+counter,counter);
                               // result -> result+counter
                               // counter -> counter
})(result,counter)

while( counter < 1e6 )
{
    add( result, counter );
    counter++;
}
console.log( result );

Bagaimana itu bekerja:

1:

Komentar kode adalah (tidak mengejutkan) semua kebohongan tetapi mereka adalah gangguan dari kebingungan utama.

2:

~ dan ^ adalah operator "bitwise not" dan "bitwise xor". Menghasilkan satu didefinisikan ulang ke -12.

3:

add diatur ke fungsi panah 6 ECMAScript "(result, counter) => (result + counter, counter)" yang tidak melakukan apa yang disarankan oleh komentar - sebaliknya ia hanya mengembalikan "counter" ekspresi terakhir dan secara efektif no-op.

4:

Ada dua variabel "hasil" - satu ditulis dalam karakter ASCII murni (dalam lingkup global) dan yang lainnya memiliki Unicode Cyrillic "ѕ" (dalam lingkup fungsi anonim yang digunakan untuk mendefinisikan add). "result = 1" me-reset nilai dalam lingkup global dan baris kedua "result = (0 |! reultult) / satu;" juga memiliki sisi kiri mengacu pada variabel "hasil" dalam lingkup global tetapi "hasil" pada sisi kanan ekspresi mengacu pada ruang lingkup fungsi dan memiliki nilai 0 (bukan nilai yang diharapkan dari 1 ) jadi nilai! reject / one = -1/12.


1

C ++

#include <iostream>
#include <limits>

#define long A
#define for(a)

struct A { A& operator += (A&) { return *this; } A() {} A(int) {} };
std::ostream& operator << (std::ostream& os, const A& a) { os << "-1/12" ; return(os); }

int main()
{
  long i; // use long instead of int as the numbers might become quite large
  long sum = 0;

  for(i = 0; i < std::numeric_limits<double>::infinity(); i++)
    sum += i;

  std::cout << sum << '\n';
}

Jika kedua #defines dihapus kode masih akan menjadi kode C ++ yang valid dan benar-benar mencoba (tapi tentu saja gagal) untuk menghitung jumlah semua bilangan bulat.

Bagaimana itu bekerja:

Arahan preprocessor mengubah kode utama menjadi:

A i;
A sum = 0;
sum += i;
std::cout << sum << '\n';

Selain mendeklarasikan Aobjek, tiga baris pertama hanyalah kebingungan. Baris terakhir melakukan semua pekerjaan menggunakan operator kelebihan beban <<pada suatu Aobjek.

Mengingat pseudocode poster saya tidak bisa menolak untuk menambahkan ini. Ini menggunakan dasar dan ide kecil yang sama tapi saya tidak berpikir itu elegan.

#include <iostream>

// defines and functions to make the code suggestion work

#define true test(counter)

uint32_t result;
uint32_t counter;

int test(uint32_t& a)
{
  static uint32_t b = 0;
  return a == 0xffffffff ? a++, ++b > 1034594986 ? 0 : 1 : 1;
}

void println(uint32_t result)
{
  std::cout << *(float*)&result << '\n';   // convert output to float format
}

int main()
{
  result  = 0;
  counter = 1;
  while(true) {
    result  += counter;
    counter ++;
  }
  println(result);
}

Bagaimana itu bekerja:

The #defineperubahan makna
while(true) {
untuk
while(test(counter)) {
Pada mesin yang diam-diam meluap setiap putaran penjumlahan sebelum overflow akan menambah 0x80000001 hasil. Karenanya setelah kenaikan b, b == hasil ketika b adalah genap dan (b + 0x80000000) == hasil ketika b adalah ganjil. 1034594986 adalah representasi integer dari angka floating point 1/12. Menambahkan 0x80000001 untuk itu akan menghasilkan bilangan bulat dekat dengan -1/12 dan fungsi tes akan mengembalikan 0 (false) dan loop akan berakhir.

Dan mengapa Anda tidak harus mencoba menjalankannya:

Jika Anda ingin melihat yang berfungsi diperingatkan: uji coba harus dipanggil 2 ^ 32 * 1034594986 kali sebelum mengakhiri loop. (Yaitu tidak dalam hidup Anda). Jika Anda ingin memverifikasi bahwa fungsi tidak seperti yang diperintahkan, gunakan debugger atau ubah program untuk melihat nilai hasil dan b tepat setelah pernyataan b ++. Ketika puas bahwa mereka sama ketika b bahkan hanya mengubah nilai awal dari b dan counter ke 1034594986. Program kemudian harus menampilkan -0,08333 setelah beberapa waktu.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.