সংকলনের সময় 1 + 2 + 3 +… + 1000 গণনা করতে সি #, সি ++ বা জাভা সংকলক কীভাবে ড্রাইভ করবেন?


122

সাম্প্রতিক এক সাক্ষাত্কারে আমাকে একটি সত্যিই অদ্ভুত প্রশ্ন জিজ্ঞাসা করা হয়েছিল। সাক্ষাত্কারকারী আমাকে জিজ্ঞাসা করলেন আমি কীভাবে কেবল সংকলক বৈশিষ্ট্যগুলি ব্যবহার করে 1 + 2 + 3 + ... + 1000 গণনা করতে পারি? এর অর্থ এই যে আমাকে কোনও প্রোগ্রাম লেখার এবং এটি সম্পাদন করার অনুমতি দেওয়া হচ্ছে না তবে আমার কেবল একটি প্রোগ্রাম লিখতে হবে যা সংকলনের সময় এই সংখ্যার গণনা করার জন্য সংকলকটি চালনা করতে পারে এবং সংকলন শেষ হলে ফলাফল মুদ্রণ করতে পারে। একটি ইঙ্গিত হিসাবে, তিনি আমাকে বলেছিলেন যে আমি সংকলকটির জেনেরিকস এবং প্রাক-প্রসেসরের বৈশিষ্ট্যগুলি ব্যবহার করতে পারি। সি ++, সি # বা জাভা সংকলক ব্যবহার করা সম্ভব। কোন ধারনা???

এই প্রশ্নটি এখানে জিজ্ঞাসা করা কোনও লুপ ছাড়াই যোগফল গণনা সম্পর্কিত নয় । তদ্ব্যতীত, এটিও লক্ষ করা উচিত যে সংকলনের সময় যোগফলটি গণনা করা উচিত। সি ++ সংকলক নির্দেশিকা ব্যবহার করে কেবল ফলাফল মুদ্রণযোগ্য তা গ্রহণযোগ্য নয়।


উত্তরসমূহ সম্পর্কে আরো পড়া, আমি ব্যবহার সি ++ টেমপ্লেট বলা হয় সংকলন করার সময় যে সমাধান সমস্যার পাওয়া metaprogramming । এটি এমন একটি প্রযুক্তি যা ডক্টর এরউইন উরুহ সি ++ ভাষা মানককরণের প্রক্রিয়া চলাকালীন দুর্ঘটনাক্রমে আবিষ্কার করেছিলেন। আপনি এই বিষয়টি সম্পর্কে মেটা-প্রোগ্রামিংয়ের উইকি পৃষ্ঠায় আরও পড়তে পারেন । দেখে মনে হচ্ছে জাভা টিকা ব্যবহার করে জাভাতে প্রোগ্রামটি লেখা সম্ভব। আপনি নীচে maress এর উত্তর এক নজরে নিতে পারেন ।

সি মেটা-প্রোগ্রামিং ++, সম্পর্কে একটি সুন্দর বই এই এক । আগ্রহী হলে একবার দেখার জন্য মূল্যবান।

একটি দরকারী সি ++ মেটা-প্রোগ্রামিং লাইব্রেরি বুস্টের এমপিএল এই লিঙ্কটি


17
#error "500500" একটি সংকলন ত্রুটি "সমাপ্ত" হিসাবে গণ্য হয়?
রহস্যময়

4
ইঙ্গিতটি মূলত আপনাকে সি ++ টেম্পলেট ব্যবহার করার জন্য বোঝায়। অবশ্যই এক নয় তবে এটি এক থেকে এক হাজারে ছাপার জন্য, আমি নিশ্চিত আপনি এক হাজারে যোগ করার জন্য এটি পরিবর্তন করতে পারবেন ... stackoverflow.com/questions/4568645/…
জো

8
const int value = 1 + 2 + 3.... + 1000; Console.WriteLine(value);; পি
জর্জ ডেকেট

8
কখনও কখনও আমি মনে করি যে কিছু সাক্ষাত্কারের প্রশ্ন কেবল ইন্টারভিউয়ের চেয়ে সাক্ষাতকারের বৌদ্ধিক শ্রেষ্ঠত্ব প্রমাণ করার জন্য জিজ্ঞাসা করা হয়।
ক্রিস দ্বোয়ার

4
আপনি এই প্রশ্ন জিজ্ঞাসা করার আগে আপনি অনেক টাকা চেয়েছিলেন?
সালমান এ

উত্তর:


118

উন্নত পুনরাবৃত্তি গভীরতার সাথে এখন আপডেট হয়েছে ! এমএসভিসি 10 এবং জিসিসিতে কোনও গভীরতা ছাড়াই কাজ করে। :)


সাধারণ সংকলন-সময় পুনরাবৃত্তি + সংযোজন:

template<unsigned Cur, unsigned Goal>
struct adder{
  static unsigned const sub_goal = (Cur + Goal) / 2;
  static unsigned const tmp = adder<Cur, sub_goal>::value;
  static unsigned const value = tmp + adder<sub_goal+1, Goal>::value;
};

template<unsigned Goal>
struct adder<Goal, Goal>{
  static unsigned const value = Goal;
};

Testcode:

template<unsigned Start>
struct sum_from{
  template<unsigned Goal>
  struct to{
    template<unsigned N>
    struct equals;

    typedef equals<adder<Start, Goal>::value> result;
  };
};

int main(){
  sum_from<1>::to<1000>::result();
}

জিসিসির জন্য আউটপুট:

ত্রুটি: 'স্ট্রাক্ট সম_ফর্ম <1u> :: থেকে <1000u> :: সমান <500500u>' এর ঘোষণা

আইডিয়নে লাইভ উদাহরণ

এমএসভিসি 10 এর আউটপুট:

error C2514: 'sum_from<Start>::to<Goal>::equals<Result>' : class has no constructors
      with
      [
          Start=1,
          Goal=1000,
          Result=500500
      ]

@ আহসালিমি: আমি উত্তরটি সম্পাদনা করেছি এমন কিছু কোড দেখানোর জন্য যা কাজটি করে দেয়। :)
Xeo

বাহ, আপনি আমাকে সত্যিই মুগ্ধ করেছেন :-)
গুপ্ত

@ আহসালিমি: ডক্টর এরউইন উরুহই ১৯৯ 1997 সালে সি ++ স্টকহোমে স্ট্যান্ডার্ডাইজেশন সভায় এই কৌশলটি আবিষ্কার করেছিলেন। তিনি কয়েকটি মৌলিক সংখ্যা গণনা করেছিলেন uted
ডায়েটমার কাহল

এটিকে পুনরাবৃত্তি না করে কাজ করতে আপনি যোগফলের জন্য N * (N + 1) / 2 সূত্রটি ব্যবহার করতে পারেন।
অ্যাডাম গ্রিট

2
@ আহসালিমি আপনি যদি সি ++ তে টেম্পলেট বিপণনের আরও অনেক দুর্দান্ত উদাহরণ দেখতে চান তবে আমি আন্দ্রেই আলেকজান্দ্রেস্কু দ্বারা আধুনিক সি ++ ডিজাইনের পরামর্শ দিচ্ছি ।
দারহুক

89

সংকলনের সময় ত্রুটির জন্য সি # উদাহরণ।

class Foo
{
    const char Sum = (1000 + 1) * 1000 / 2;
}

নিম্নলিখিত সংকলন ত্রুটি উত্পাদন করে:

Constant value '500500' cannot be converted to a 'char' 

4
@ildjarn ওয়েল সি ++ টেম্পলেট উত্তর এবং এটির মধ্যে একটি পার্থক্য আছে: এটি কেবল ধ্রুবক ভাঁজ করার কারণে কাজ করে যখন টেমপ্লেটটি স্বেচ্ছাসেবক (?) কোডের অনুমতি দেয়। এটি একটি চরকে বরাদ্দ করা এখনও একটি ভাল ধারণা!
ভু

@ ভু হ্যাঁ, তবে সি সি ন্যায্য হতে এই ধরণের প্রোগ্রামিংয়ের জন্য কেবল সি ++ এর সাথে তুলনা করা হয় না।
মারলন

3
@ মেরিওন এবং আমি সত্যিই বিবেচনা করি না যে ভাষা ডিজাইনের কোনও ভুল;) টেমপ্লেট মেটা প্রোগ্রামিং সমস্ত শক্তিশালী হতে পারে তবে অন্যান্য ভাষাগুলি এখনও অন্যান্য সমাধানগুলির সাথে বেশিরভাগ জিনিসই করতে পারে যার মধ্যে সমস্ত সমস্যা নেই। আমাকে এমন একটি প্রকল্পে কাজ করতে হয়েছিল যা সংকলন করতে কয়েক ঘন্টা সময় নিয়েছিল (সম্পূর্ণ সত্য নয় - এটি অবিশ্বাস্যরূপে দ্রুত ছিল যদি আমরা পুনরাবৃত্ত ইনস্ট্যান্টেশন সীমা না বাড়িয়ে দিয়েছিলাম .. এটি কয়েক সেকেন্ডে ব্যর্থ হয়েছিল) এবং এটি বজায় রাখা ভয়াবহ ছিল। সম্ভবত এটির কারণেই আমি এর খুব বেশি অনুরাগী নই ..
ভু

@ ভু: ফ্রেডওভারফ্লো এর পদ্ধতির পাশাপাশি ধ্রুবক ভাঁজও নির্ভর করে। ধীরে ধীরে সংকলন হিসাবে, আপনার সংকলকটিকে দোষ দিন, ভাষা নয় (ইঙ্গিত - ঝনঝনানো সি ++ দ্রুত কম্পাইল করে )।
iljarn

@ ইল্ডার্ন ক্ল্যাং অত্যন্ত জটিল, সত্যই গভীরভাবে বাসা বাঁধে এবং মারাত্মক জটিল টেম্পলেটগুলি দ্রুত সংকলন করে? আমি সবকিছুই সম্ভব বলে ধরে নিয়েছি এবং আমি এটি আর পরীক্ষা করতে পারি না (godশ্বরের ধন্যবাদ) তবে আমি এটি কল্পনাও করতে পারি না। এছাড়াও আমি এখানে ফ্রেডের নয়, জিওর পদ্ধতির কথা বলছি।
ভু

51

আমার কেবল একটি প্রোগ্রাম লিখতে হবে যা সংকলনের সময় এই অঙ্কটি গণনা করতে সংকলকটিকে ড্রাইভ করতে পারে এবং সংকলন শেষ হলে ফলাফল মুদ্রণ করতে পারে।

সংকলনের সময় একটি সংখ্যা মুদ্রণের জন্য একটি জনপ্রিয় কৌশলটি আপনি যে নম্বরটি মুদ্রণ করতে চান তা দিয়ে ইনস্টল করা টেম্পলেটটির অস্তিত্বহীন সদস্যকে অ্যাক্সেস করার চেষ্টা করছে:

template<int> struct print_n {};

print_n<1000 * 1001 / 2>::foobar go;

সংকলকটি তখন বলে:

error: 'foobar' in 'struct print_n<500500>' does not name a type

এই প্রযুক্তিটি একটি বেশি আকর্ষণীয় উদাহরণস্বরূপ, দেখুন কম্পাইল-সময়ে আট কুইন্স সমস্যা সমাধান


আপনি ঠিক পাশাপাশি অপরিশোধিত print_nথাকতে পারেন, আমার উত্তর দেখুন।
শিও

2
@ ডেভিড তবে গাউসের একটি চতুর পথের প্রয়োজন ছিল, বোকা উপায়ে দ্রুত এটি করার জন্য তার কাছে কম্পিউটার ছিল না।
ড্যানিয়েল ফিশার

31

যেহেতু সাক্ষাত্কারের প্রশ্নে সংকলক বা ভাষা উভয়ই নির্দিষ্ট করা হয়নি, তাই আমি জিএইচসি ব্যবহার করে হাসকেলে একটি সমাধান জমা দেওয়ার সাহস করব:

{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -ddump-splices #-}
module Main where

main :: IO ()
main = print $(let x = sum [1 :: Int .. 1000] in [| x |])

এটি সংকলন:

$ ghc compsum.hs
[1 of 1] Compiling Main             ( compsum.hs, compsum.o )
Loading package ghc-prim ... linking ... done.
<snip more "Loading package ..." messages>
Loading package template-haskell ... linking ... done.
compsum.hs:6:16-56: Splicing expression
    let x = sum [1 :: Int .. 1000] in [| x |] ======> 500500
Linking compsum ...

এবং আমরা একটি কর্মসূচি প্রোগ্রাম পেয়েছিলাম।


20

সি ++ 11 দিয়ে জীবন অনেক সহজ হবে যা constexprসংকলনের সময় গণনার জন্য ফাংশন যুক্ত করে, যদিও তারা বর্তমানে কেবল জিসিসি 4.6 বা তার পরে সমর্থন করে।

constexpr unsigned sum(unsigned start, unsigned end) {
    return start == end ? start :
        sum(start, (start + end) / 2) +
        sum((start + end) / 2 + 1, end);
}

template <int> struct equals;
equals<sum(1,1000)> x;

স্ট্যান্ডার্ডটির জন্য কেবল 512 এর পুনরাবৃত্তির গভীরতা সমর্থন করার জন্য সংকলকটির প্রয়োজন, সুতরাং এটি এখনও লিনিয়ার পুনরাবৃত্তির গভীরতা এড়াতে হবে। এখানে ফলাফল:

$ g++-mp-4.6 --std=c++0x test.cpp -c
test.cpp:8:25: error: aggregate 'equals<500500> x' has incomplete type and cannot be defined

অবশ্যই আপনি সূত্রটি ব্যবহার করতে পারেন:

constexpr unsigned sum(unsigned start, unsigned end) {
    return (start + end) * (end - start + 1) / 2;
}

// static_assert is a C++11 assert, which checks
// at compile time.
static_assert(sum(0,1000) == 500500, "Sum failed for 0 to 1000");

1
+1, constexprএক মুহুর্তের জন্য পুরোপুরি ভুলে গেছি । আমি কেবল টেমপ্লেটগুলি খুব বেশি পছন্দ করি। :(
Xeo

প্রশ্নটি সম্বোধন করার জন্য এটি কনটেক্সট্রপের একটি দুর্দান্ত ব্যবহার (অ্যাড্ডার বাস্তবায়ন দেখুন): কাইজার.সেস
ম্যাট

সেই সূত্রটি উপচে পড়তে পারে; শেষ পদক্ষেপটি হ'ল / 2সম্ভাব্য unsignedফলাফলের সম্পূর্ণ পরিসরটি পরিচালনা করতে , আপনি যে মানটি ডানদিকের স্থানান্তর করছেন তা n + 1 বিট প্রশস্ত হতে হবে, তবে তা নয়। এড়াতে সূত্রটি পুনরায় সাজানো সম্ভব, যেমন ক্লাং রানটাইম-ভেরিয়েবল রেঞ্জের জন্য করে: গডবোল্ট.অর্গ / জেড / ডিইউজিএক্সকিগ দেখায় যে ক্ল্যাং বন্ধ-ফর্মুলাটি জানে এবং total += iলুপগুলি অনুকূল করতে এটি ব্যবহার করে ।
পিটার কর্ডেস

14

জাভাতে, আমি এ্যানোটেশন প্রক্রিয়াকরণটি ব্যবহার করার বিষয়ে চিন্তা করেছি। অ্যাভেট সরঞ্জামটি জাভাক কমান্ডটিতে উত্স ফাইলটি পার্স করার আগে উত্স ফাইলটি স্ক্যান করে।

উত্স ফাইলগুলি সংকলনের সময়, আউটপুট প্রিন্ট করা হবে:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyInterface {

    int offset() default 0;

    int last() default 100;
}

প্রসেসর কারখানা:

public class MyInterfaceAnnotationProcessorFactory implements AnnotationProcessorFactory {

    public Collection<String> supportedOptions() {
        System.err.println("Called supportedOptions.............................");
        return Collections.EMPTY_LIST;
    }

    public Collection<String> supportedAnnotationTypes() {
        System.err.println("Called supportedAnnotationTypes...........................");
        return Collections.singletonList("practiceproject.MyInterface");
    }

    public AnnotationProcessor getProcessorFor(Set<AnnotationTypeDeclaration> set, AnnotationProcessorEnvironment ape) {
        System.err.println("Called getProcessorFor................");
        if (set.isEmpty()) {
            return AnnotationProcessors.NO_OP;
        }
        return new MyInterfaceAnnotationProcessor(ape);
    }
}

আসল টীকা প্রসেসর:

public class MyInterfaceAnnotationProcessor implements AnnotationProcessor {

    private AnnotationProcessorEnvironment ape;
    private AnnotationTypeDeclaration atd;

    public MyInterfaceAnnotationProcessor(AnnotationProcessorEnvironment ape) {
        this.ape = ape;
        atd = (AnnotationTypeDeclaration) ape.getTypeDeclaration("practiceproject.MyInterface");
    }

    public void process() {
        Collection<Declaration> decls = ape.getDeclarationsAnnotatedWith(atd);
        for (Declaration dec : decls) {
            processDeclaration(dec);
        }
    }

    private void processDeclaration(Declaration d) {
        Collection<AnnotationMirror> ams = d.getAnnotationMirrors();
        for (AnnotationMirror am : ams) {
            if (am.getAnnotationType().getDeclaration().equals(atd)) {
                Map<AnnotationTypeElementDeclaration, AnnotationValue> values = am.getElementValues();
                int offset = 0;
                int last = 100;
                for (Map.Entry<AnnotationTypeElementDeclaration, AnnotationValue> entry : values.entrySet()) {
                    AnnotationTypeElementDeclaration ated = entry.getKey();
                    AnnotationValue v = entry.getValue();
                    String name = ated.getSimpleName();
                    if (name.equals("offset")) {
                        offset = ((Integer) v.getValue()).intValue();
                    } else if (name.equals("last")) {
                        last = ((Integer) v.getValue()).intValue();
                    }
                }
                //find the sum
                System.err.println("Sum: " + ((last + 1 - offset) / 2) * (2 * offset + (last - offset)));
            }
        }
    }
}

তারপরে আমরা একটি উত্স ফাইল তৈরি করি। মাইআইন্টারফেস টীকাটি ব্যবহার করে এমন সাধারণ ক্লাস:

 @MyInterface(offset = 1, last = 1000)
public class Main {

    @MyInterface
    void doNothing() {
        System.out.println("Doing nothing");
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        Main m = new Main();
        m.doNothing();
        MyInterface my = (MyInterface) m.getClass().getAnnotation(MyInterface.class);
        System.out.println("offset: " + my.offset());
        System.out.println("Last: " + my.last());
    }
}

টীকাগুলি প্রসেসরটি একটি জার ফাইলে সংকলিত হয়, তবে উত্স সরঞ্জামটি উত্স ফাইলটি সংকলন করতে ব্যবহৃত হয়:

apt -cp "D:\Variance project\PracticeProject\dist\practiceproject.jar" -factory practiceproject.annotprocess.MyInterfaceAnnotationProcessorFactory "D:\Variance project\PracticeProject2\src\practiceproject2\Main.java"

প্রকল্পের আউটপুট:

Called supportedAnnotationTypes...........................
Called getProcessorFor................
Sum: 5000
Sum: 500500

9

ভিসি ++ ২০১০ এর অধীনে কাজ করা এমন একটি বাস্তবায়ন এখানে রয়েছে the

template<int t_startVal, int t_baseVal = 0, int t_result = 0>
struct SumT
{
    enum { result = SumT<t_startVal - 1, t_baseVal, t_baseVal + t_result +
        t_startVal>::result };
};

template<int t_baseVal, int t_result>
struct SumT<0, t_baseVal, t_result>
{
    enum { result = t_result };
};

template<int output_value>
struct Dump
{
    enum { value = output_value };
    int bad_array[0];
};

enum
{
    value1 = SumT<400>::result,                // [1,400]
    value2 = SumT<400, 400, value1>::result,   // [401, 800]
    value3 = SumT<200, 800, value2>::result    // [801, 1000]
};

Dump<value3> dump;

আপনি যখন এটি সংকলন করেন, আপনার এই আউটপুটটি সংকলকটির থেকে দেখে নেওয়া উচিত:

1>warning C4200: nonstandard extension used : zero-sized array in struct/union
1>          Cannot generate copy-ctor or copy-assignment operator when UDT contains a 
zero-sized array
1>          templatedrivensum.cpp(33) : see reference to class template 
instantiation 'Dump<output_value>' being compiled
1>          with
1>          [
1>              output_value=500500
1>          ]

এটি ভেঙে দেওয়ার সাথে খুব সুন্দর ধারণা, আমি মনে করি আমি এটি কোনওভাবেই আমার উত্তরটিতে অন্তর্ভুক্ত করব। +1 :)
Xoo

9

আমি এই সি কোড দিতে বাধ্য বোধ করছি, যেহেতু অন্য কারও কাছে এখনও নেই:

#include <stdio.h>
int main() {
   int x = 1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+
           21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+
           41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+
           61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79+80+
           81+82+83+84+85+86+87+88+89+90+91+92+93+94+95+96+97+98+99+100+     
           101+102+103+104+105+106+107+108+109+110+111+112+113+114+115+116+117+118+119+120+
           121+122+123+124+125+126+127+128+129+130+131+132+133+134+135+136+137+138+139+140+
           141+142+143+144+145+146+147+148+149+150+151+152+153+154+155+156+157+158+159+160+
           161+162+163+164+165+166+167+168+169+170+171+172+173+174+175+176+177+178+179+180+
           181+182+183+184+185+186+187+188+189+190+191+192+193+194+195+196+197+198+199+200+
           201+202+203+204+205+206+207+208+209+210+211+212+213+214+215+216+217+218+219+220+
           221+222+223+224+225+226+227+228+229+230+231+232+233+234+235+236+237+238+239+240+
           241+242+243+244+245+246+247+248+249+250+251+252+253+254+255+256+257+258+259+260+
           261+262+263+264+265+266+267+268+269+270+271+272+273+274+275+276+277+278+279+280+
           281+282+283+284+285+286+287+288+289+290+291+292+293+294+295+296+297+298+299+300+
           301+302+303+304+305+306+307+308+309+310+311+312+313+314+315+316+317+318+319+320+
           321+322+323+324+325+326+327+328+329+330+331+332+333+334+335+336+337+338+339+340+
           341+342+343+344+345+346+347+348+349+350+351+352+353+354+355+356+357+358+359+360+
           361+362+363+364+365+366+367+368+369+370+371+372+373+374+375+376+377+378+379+380+
           381+382+383+384+385+386+387+388+389+390+391+392+393+394+395+396+397+398+399+400+
           401+402+403+404+405+406+407+408+409+410+411+412+413+414+415+416+417+418+419+420+
           421+422+423+424+425+426+427+428+429+430+431+432+433+434+435+436+437+438+439+440+
           441+442+443+444+445+446+447+448+449+450+451+452+453+454+455+456+457+458+459+460+
           461+462+463+464+465+466+467+468+469+470+471+472+473+474+475+476+477+478+479+480+
           481+482+483+484+485+486+487+488+489+490+491+492+493+494+495+496+497+498+499+500+
           501+502+503+504+505+506+507+508+509+510+511+512+513+514+515+516+517+518+519+520+
           521+522+523+524+525+526+527+528+529+530+531+532+533+534+535+536+537+538+539+540+
           541+542+543+544+545+546+547+548+549+550+551+552+553+554+555+556+557+558+559+560+
           561+562+563+564+565+566+567+568+569+570+571+572+573+574+575+576+577+578+579+580+
           581+582+583+584+585+586+587+588+589+590+591+592+593+594+595+596+597+598+599+600+
           601+602+603+604+605+606+607+608+609+610+611+612+613+614+615+616+617+618+619+620+
           621+622+623+624+625+626+627+628+629+630+631+632+633+634+635+636+637+638+639+640+
           641+642+643+644+645+646+647+648+649+650+651+652+653+654+655+656+657+658+659+660+
           661+662+663+664+665+666+667+668+669+670+671+672+673+674+675+676+677+678+679+680+
           681+682+683+684+685+686+687+688+689+690+691+692+693+694+695+696+697+698+699+700+
           701+702+703+704+705+706+707+708+709+710+711+712+713+714+715+716+717+718+719+720+
           721+722+723+724+725+726+727+728+729+730+731+732+733+734+735+736+737+738+739+740+
           741+742+743+744+745+746+747+748+749+750+751+752+753+754+755+756+757+758+759+760+
           761+762+763+764+765+766+767+768+769+770+771+772+773+774+775+776+777+778+779+780+
           781+782+783+784+785+786+787+788+789+790+791+792+793+794+795+796+797+798+799+800+
           801+802+803+804+805+806+807+808+809+810+811+812+813+814+815+816+817+818+819+820+
           821+822+823+824+825+826+827+828+829+830+831+832+833+834+835+836+837+838+839+840+
           841+842+843+844+845+846+847+848+849+850+851+852+853+854+855+856+857+858+859+860+
           861+862+863+864+865+866+867+868+869+870+871+872+873+874+875+876+877+878+879+880+
           881+882+883+884+885+886+887+888+889+890+891+892+893+894+895+896+897+898+899+900+
           901+902+903+904+905+906+907+908+909+910+911+912+913+914+915+916+917+918+919+920+
           921+922+923+924+925+926+927+928+929+930+931+932+933+934+935+936+937+938+939+940+
           941+942+943+944+945+946+947+948+949+950+951+952+953+954+955+956+957+958+959+960+
           961+962+963+964+965+966+967+968+969+970+971+972+973+974+975+976+977+978+979+980+
           981+982+983+984+985+986+987+988+989+990+991+992+993+994+995+996+997+998+999+1000;
  printf("%d\n", x);
}

এবং আমাকে যা করতে হবে তা হল আমার উত্তরটি সন্ধানের জন্য অ্যাসেম্বলি পরীক্ষা করা!

gcc -S compile_sum.c;
grep "\$[0-9]*, *-4" compile_sum.s

এবং আমি দেখতে পাচ্ছি:

movl    $500500, -4(%rbp)

নির্দিষ্ট ভাষা প্রয়োগের বৈশিষ্ট্য, সি ভাষা নয়।
কুকুরছানা

5
আপনি কতটি সি সংকলক জানেন যে এটি সি এর "নির্দিষ্ট প্রয়োগ" নয়?
কার্ল ওয়ালশ

@ পপি: xবিশ্বব্যাপী হলে সংকলকটি সংকলনের সময় প্রকাশের মূল্যায়ন করার জন্য (কম বেশি) প্রয়োজন হত। আইএসও সি গ্লোবালের জন্য রানটাইম-ভেরিয়েবল ইনিশিয়েলাইজারদের অনুমতি দেয় না। অবশ্যই একটি নির্দিষ্ট বাস্তবায়ন কন্সট্রাক্টরের মতো স্ট্যাটিক-থ্রি ফাংশনে কল প্রেরণ করতে পারে যা এটি রানটাইম এবং স্টোরগুলিতে গণনা করে। তবে আইএসও সি আপনাকে সংকলিত সময় ধ্রুবকগুলি অ্যারের আকার হিসাবে ব্যবহার করতে দেয় ( int y[x];যেমন কোনও কাঠামোর সংজ্ঞা বা অন্য কোনও বিশ্বব্যাপী উদাহরণস্বরূপ), সুতরাং যে কোনও অনুমানমূলক হতাশার বাস্তবায়ন এখনও তাকে সমর্থন করতে হবে।
পিটার কর্ডেস

7

সংকলনের সময় ফলাফলটি মুদ্রণের জন্য কার্ল ওয়ালশের উত্তর থেকে প্রসারিত:

#define VALUE (1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+\
21+22+23+24+25+26+27+28+29+30+31+32+33+34+35+36+37+38+39+40+\
41+42+43+44+45+46+47+48+49+50+51+52+53+54+55+56+57+58+59+60+\
61+62+63+64+65+66+67+68+69+70+71+72+73+74+75+76+77+78+79+80+\
81+82+83+84+85+86+87+88+89+90+91+92+93+94+95+96+97+98+99+100+\
101+102+103+104+105+106+107+108+109+110+111+112+113+114+115+116+117+118+119+120+\
121+122+123+124+125+126+127+128+129+130+131+132+133+134+135+136+137+138+139+140+\
141+142+143+144+145+146+147+148+149+150+151+152+153+154+155+156+157+158+159+160+\
161+162+163+164+165+166+167+168+169+170+171+172+173+174+175+176+177+178+179+180+\
181+182+183+184+185+186+187+188+189+190+191+192+193+194+195+196+197+198+199+200+\
201+202+203+204+205+206+207+208+209+210+211+212+213+214+215+216+217+218+219+220+\
221+222+223+224+225+226+227+228+229+230+231+232+233+234+235+236+237+238+239+240+\
241+242+243+244+245+246+247+248+249+250+251+252+253+254+255+256+257+258+259+260+\
261+262+263+264+265+266+267+268+269+270+271+272+273+274+275+276+277+278+279+280+\
281+282+283+284+285+286+287+288+289+290+291+292+293+294+295+296+297+298+299+300+\
301+302+303+304+305+306+307+308+309+310+311+312+313+314+315+316+317+318+319+320+\
321+322+323+324+325+326+327+328+329+330+331+332+333+334+335+336+337+338+339+340+\
341+342+343+344+345+346+347+348+349+350+351+352+353+354+355+356+357+358+359+360+\
361+362+363+364+365+366+367+368+369+370+371+372+373+374+375+376+377+378+379+380+\
381+382+383+384+385+386+387+388+389+390+391+392+393+394+395+396+397+398+399+400+\
401+402+403+404+405+406+407+408+409+410+411+412+413+414+415+416+417+418+419+420+\
421+422+423+424+425+426+427+428+429+430+431+432+433+434+435+436+437+438+439+440+\
441+442+443+444+445+446+447+448+449+450+451+452+453+454+455+456+457+458+459+460+\
461+462+463+464+465+466+467+468+469+470+471+472+473+474+475+476+477+478+479+480+\
481+482+483+484+485+486+487+488+489+490+491+492+493+494+495+496+497+498+499+500+\
501+502+503+504+505+506+507+508+509+510+511+512+513+514+515+516+517+518+519+520+\
521+522+523+524+525+526+527+528+529+530+531+532+533+534+535+536+537+538+539+540+\
541+542+543+544+545+546+547+548+549+550+551+552+553+554+555+556+557+558+559+560+\
561+562+563+564+565+566+567+568+569+570+571+572+573+574+575+576+577+578+579+580+\
581+582+583+584+585+586+587+588+589+590+591+592+593+594+595+596+597+598+599+600+\
601+602+603+604+605+606+607+608+609+610+611+612+613+614+615+616+617+618+619+620+\
621+622+623+624+625+626+627+628+629+630+631+632+633+634+635+636+637+638+639+640+\
641+642+643+644+645+646+647+648+649+650+651+652+653+654+655+656+657+658+659+660+\
661+662+663+664+665+666+667+668+669+670+671+672+673+674+675+676+677+678+679+680+\
681+682+683+684+685+686+687+688+689+690+691+692+693+694+695+696+697+698+699+700+\
701+702+703+704+705+706+707+708+709+710+711+712+713+714+715+716+717+718+719+720+\
721+722+723+724+725+726+727+728+729+730+731+732+733+734+735+736+737+738+739+740+\
741+742+743+744+745+746+747+748+749+750+751+752+753+754+755+756+757+758+759+760+\
761+762+763+764+765+766+767+768+769+770+771+772+773+774+775+776+777+778+779+780+\
781+782+783+784+785+786+787+788+789+790+791+792+793+794+795+796+797+798+799+800+\
801+802+803+804+805+806+807+808+809+810+811+812+813+814+815+816+817+818+819+820+\
821+822+823+824+825+826+827+828+829+830+831+832+833+834+835+836+837+838+839+840+\
841+842+843+844+845+846+847+848+849+850+851+852+853+854+855+856+857+858+859+860+\
861+862+863+864+865+866+867+868+869+870+871+872+873+874+875+876+877+878+879+880+\
881+882+883+884+885+886+887+888+889+890+891+892+893+894+895+896+897+898+899+900+\
901+902+903+904+905+906+907+908+909+910+911+912+913+914+915+916+917+918+919+920+\
921+922+923+924+925+926+927+928+929+930+931+932+933+934+935+936+937+938+939+940+\
941+942+943+944+945+946+947+948+949+950+951+952+953+954+955+956+957+958+959+960+\
961+962+963+964+965+966+967+968+969+970+971+972+973+974+975+976+977+978+979+980+\
981+982+983+984+985+986+987+988+989+990+991+992+993+994+995+996+997+998+999+1000)

char tab[VALUE];

int main()
{
    tab = 5;
}

জিসিসি আউটপুট:

test.c: In function 'main':
test.c:56:9: error: incompatible types when assigning to type 'char[500500]' fro
m type 'int'

2

আপনি রূপান্তর করতে সি ++ ম্যাক্রোগ / টেম্পলেট ব্যবহার করতে পারেন (এবং বেশিরভাগ আপত্তিজনক) । আফাইক, জাভা একই ধরণের জিনিসকে অনুমতি দেয় না।


2
আসলেই প্রশ্নের উত্তর নয়।
ইক্কে 7'12

আমি আপনি ঠিক মনে করেন. জাভাতে আপনি একই টেম্পলেট পুনরাবৃত্তি কৌশল ব্যবহার করতে পারবেন না, যেহেতু জেনেরিক ক্লাসের প্যারামিটারের মান হতে পারে না - এটি অবশ্যই একটি শ্রেণি হতে হবে।
আইয়াল স্নাইডার

সি # সংকলকের জেনেরিক বৈশিষ্ট্য আপনাকে কিছু সংকলন-সময় গণনা করতে দেয়। এটি সম্পর্কে এরিক লিপার্টের পোস্টটি দেখুন ।
অ্যালন গুরালেনেক

1

তত্ত্বগতভাবে, আপনি এটি ব্যবহার করতে পারেন:

#include <iostream>

template<int N>
struct Triangle{
  static int getVal()
  {
    return N + Triangle<N-1>::getVal();
  }
};

template<>
struct Triangle<1>{
  static int getVal()
  {
    return 1;
  }
};

int main(){
   std::cout << Triangle<1000>::getVal() << std::endl;
   return 0;
}

(জিও পোস্ট করা কোডের উপর ভিত্তি করে)। তবে জিসিসি আমাকে এই ত্রুটি দেয়:

triangle.c++:7: error: template instantiation depth exceeds maximum of 500 (use -ftemplate-depth-NN to increase the maximum) instantiating struct Triangle<500>

প্লাস একটি বিরাট সিউডো-স্ট্যাকট্রেস।


পতাকাটি ব্যবহার করতে হবে: -ফ্লেমপ্লেট-গভীরতা -1000
জেটি

@ আহসালিমি: হ্যাঁ। একবার আপনি পতাকা যুক্ত করলে এটি 1000 এর জন্যও কাজ করে। তবে এটি সংকলন-সময়ে মুদ্রণ করে না , এবং জিয়ো এই নির্দিষ্ট সমস্যার উত্তর দেওয়ার জন্য তার উত্তরটি পরিবর্তন করেছে, তাই আমার মনে হয় আমার উত্তরটি অপ্রচলিত। :-)
রূখ

1

জাভা ব্যবহার করে আপনি সি # উত্তরের অনুরূপ কাজ করতে পারেন:

public class Cheat {
    public static final int x = (1000 *1001/2);
}

javac -Xprint Cheat.java

public class Cheat {

  public Cheat();
  public static final int x = 500500;
}

আপনি পেনো সংখ্যা ব্যবহার করে স্কেলে এটি করতে পারেন কারণ আপনি সংকলককে পুনরাবৃত্তি করতে বাধ্য করতে পারেন তবে আমি মনে করি না আপনি সি # / জাভাতেও একই জিনিসটি করতে পারবেন

এক্স-প্রিন্ট ব্যবহার না করে আরও ডডজি সমাধান করার একটি অন্য সমাধান

public class Cheat {
  public static final int x = 5/(1000 *1001/2 - 500500);
}

javac -Xlint:all Cheat.java

Cheat.java:2: warning: [divzero] division by zero
  public static final int x = 5/(1000 *1001/2 - 500500);
                            ^
1 warning

কোনও সংকলক পতাকা ব্যবহার ছাড়াই। যেহেতু আপনি স্থবির সংখ্যক (কেবল 500500 নয়) পরীক্ষা করতে পারেন এই সমাধানটি গ্রহণযোগ্য হবে।

public class Cheat {
  public static final short max = (Short.MAX_VALUE - 500500) + 1001*1000/2;
  public static final short overflow = (Short.MAX_VALUE - 500500 + 1) + 1001*1000/2;

}

Cheat.java:3: error: possible loss of precision
  public static final short overflow = (Short.MAX_VALUE - 500500 + 1) + 1001*1000/2;
                                                                  ^
  required: short
  found:    int
1 error

আপনি কম্পাইলারটি গণনা করার জন্য চালনা করেননি 500500, দুঃখিত।
জিও

1
এটি কি তিনটি সমাধানের রেফারেন্সে? সমাধান 1 এ আমি কিছু জাভা কোড নিয়েছি এবং এটি সংকলন করেছি এবং সংকলকটি 500500 মুদ্রিত করেছি that এটি দেখতে অনেকটা সংকলক 500500 সংখ্যার তুলনায়।
benmmurphy

হ্যাঁ, যথেষ্ট সত্য, আমি সমাধান 2 এবং 3 সম্পর্কে কথা বলছিলাম আমি এই উত্তরটি ইতিমধ্যে একটি পূর্ববর্তী আপডেটে পড়েছি এবং নতুনটিতে ফিরে এসেছি এবং মনে হয় প্রথম সমাধানটি ভুলে গিয়েছি।
জিও

আমি বলব যে সমাধান 2 এবং 3 এটিও গণনা করছে। আপনি মূলত যা করছেন তাই আপনি একটি নির্বিচারে চেক যোগ করতে পারেন for (i = 0; i < 100000; ++i) {if (i == 1000*1000/2) print i}। আমার একটি 160mb জাভা ফাইল রয়েছে যা এটি করে এবং এটি কাজ করে :)
বেনমুরফি

1

যদিও এটি আসলে অল্প সংখ্যার সাথে কাজ করে, ঝাঁকুনি ++ আমাকে একটি সংকলক ত্রুটি প্রদান করে যদি আমি Sum_first যেখানে N> 400 ব্যবহার করি।

#include <iostream>

using namespace std;


template <int N>
struct sum_first
{
   static const int value = N + sum_first<N - 1>::value;
};

template <>
struct sum_first<0>
{
    static const int value = 0;
};

int main()
{
    cout << sum_first<1000>::value << endl;
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.